Replicator: blur images when I have moving objects

Hi,
I want to to generate synthetic data of a robot manipulator with random camera poses and joint positions. I did a minimal example based on randomization_demo.py.
The problem is that the robot moves when the writer is rendering/saving the images, and consequently, the generated images are blurry. How could I circumvent this?

Generated image:

I really apreciate if anyone can help me.

Thank you in advance,

Juan

Minimal example:

from omni.isaac.kit import SimulationApp


CONFIG = {"renderer": "PathTracing", "headless": False, "width": 512, "height": 512, "num_frames": 10, "multi_gpu": True}
simulation_app = SimulationApp(CONFIG)

import carb
import numpy as np
from omni.isaac.core import World
from omni.isaac.core.prims import RigidPrimView
from omni.isaac.core.articulations import ArticulationView
from omni.isaac.core.utils.prims import get_prim_at_path, define_prim
from omni.isaac.core.utils.stage import get_current_stage, add_reference_to_stage
from omni.isaac.core.utils.nucleus import get_assets_root_path
from omni.isaac.core.objects import DynamicSphere
from omni.isaac.cloner import GridCloner

# create the world
world = World(stage_units_in_meters=1.0, physics_prim_path="/physicsScene", backend="numpy")

assets_root_path = get_assets_root_path()
if assets_root_path is None:
    carb.log_error("Could not find Isaac Sim assets folder, closing app..")
    simulation_app.close()
usd_path = assets_root_path + "/Isaac/Environments/Grid/default_environment.usd"
add_reference_to_stage(usd_path=usd_path, prim_path="/World/defaultGroundPlane")

# set up grid cloner
cloner = GridCloner(spacing=1.5)
cloner.define_base_env("/World/envs")
define_prim("/World/envs/env_0")

# set up the first environment
DynamicSphere(prim_path="/World/envs/env_0/object", radius=0.1, position=np.array([0.75, 0.0, 0.2]))
add_reference_to_stage(
    usd_path=assets_root_path + "/Isaac/Robots/Franka/franka.usd", prim_path="/World/envs/env_0/franka"
)

# clone environments
num_envs = 1
prim_paths = cloner.generate_paths("/World/envs/env", num_envs)
env_pos = cloner.clone(source_prim_path="/World/envs/env_0", prim_paths=prim_paths)

# creates the views and set up world
object_view = RigidPrimView(prim_paths_expr="/World/envs/*/object", name="object_view")
franka_view = ArticulationView(prim_paths_expr="/World/envs/*/franka", name="franka_view")
world.scene.add(object_view)
world.scene.add(franka_view)
world.reset()

num_dof = franka_view.num_dof

# set up randomization with omni.replicator.isaac, imported as dr
import omni.replicator.isaac as dr
import omni.replicator.core as rep

dr.physics_view.register_simulation_context(world)
dr.physics_view.register_rigid_prim_view(object_view)
dr.physics_view.register_articulation_view(franka_view)

with dr.trigger.on_rl_frame(num_envs=num_envs):
    with dr.gate.on_interval(interval=20):
        dr.physics_view.randomize_simulation_context(
            operation="scaling", gravity=rep.distribution.uniform((1, 1, 0.0), (1, 1, 2.0))
        )
    with dr.gate.on_interval(interval=50):
        dr.physics_view.randomize_rigid_prim_view(
            view_name=object_view.name, operation="direct", force=rep.distribution.uniform((0, 0, 2.5), (0, 0, 5.0))
        )
    with dr.gate.on_interval(interval=10):
        dr.physics_view.randomize_articulation_view(
            view_name=franka_view.name,
            operation="direct",
            joint_velocities=rep.distribution.uniform(tuple([-2] * num_dof), tuple([2] * num_dof)),
        )
    with dr.gate.on_env_reset():
        dr.physics_view.randomize_rigid_prim_view(
            view_name=object_view.name,
            operation="additive",
            position=rep.distribution.normal((0.0, 0.0, 0.0), (0.2, 0.2, 0.0)),
            velocity=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
        )
        dr.physics_view.randomize_articulation_view(
            view_name=franka_view.name,
            operation="additive",
            joint_positions=rep.distribution.uniform(tuple([-0.5] * num_dof), tuple([0.5] * num_dof)),
            position=rep.distribution.normal((0.0, 0.0, 0.0), (0.2, 0.2, 0.0)),
        )

frames = 1000
camera = rep.create.camera(position=(3, 3, 3), clipping_range=(0.01, 10000.0))
#rep.set_global_seed(23)
rep.settings.set_render_pathtraced(samples_per_pixel=512)
rep.settings.carb_settings("/omni/replicator/RTSubframes", 3)
render_product = rep.create.render_product(camera, (512, 512)) 

with rep.trigger.on_frame(num_frames=frames, interval=1,  rt_subframes=3):   
        with camera:
            rep.modify.pose(   
                    position=rep.distribution.uniform((2, 2, 2), (4, 4, 4)),
                    look_at="/World/envs/env_0/franka",
                    #scale=rep.distribution.uniform(0.1, 2)
                )
# Initialize and attach writer
writer = rep.WriterRegistry.get("BasicWriter") 
output_directory = r"E:\output\_out_sdrec_1"
print("Outputting data to ", output_directory)     
writer.initialize(
        output_dir=output_directory,
        rgb=True,
    )   
writer.attach([render_product])   

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

frame_idx = 0
while simulation_app.is_running():
    if world.is_playing():
        reset_inds = list()
        if frame_idx % 200 == 0:
            # triggers reset every 200 steps
            reset_inds = np.arange(num_envs)
        dr.physics_view.step_randomization(reset_inds)
        world.step(render=True)
        frame_idx += 1

simulation_app.close()

Hi @juanjqo - Someone from our team will look at the problem and respond to you.

@rthaker Thank you very much!

Hi there,

can you check if rep.orchestrator.step() instead of run() solves the issue:

while simulation_app.is_running():
    if world.is_playing():
        reset_inds = list()
        if frame_idx % 200 == 0:
            # triggers reset every 200 steps
            reset_inds = np.arange(num_envs)
        dr.physics_view.step_randomization(reset_inds)

        # trigger replicator randomizers and data collection
        rep.orchestrator.step()

        world.step(render=True)
        frame_idx += 1

@rthaker thank you for your reply. I tested it, and it is not working. The robot does not move. Furthermore, the camera is static. This is, there are no random camera poses, and the camera is not oriented to the object (“/World/envs/env_0/franka”).

Generated image:

Code after modifications:

from omni.isaac.kit import SimulationApp


CONFIG = {"renderer": "PathTracing", "headless": False, "width": 512, "height": 512, "num_frames": 10, "multi_gpu": True}
simulation_app = SimulationApp(CONFIG)

import carb
import numpy as np
from omni.isaac.core import World
from omni.isaac.core.prims import RigidPrimView
from omni.isaac.core.articulations import ArticulationView
from omni.isaac.core.utils.prims import get_prim_at_path, define_prim
from omni.isaac.core.utils.stage import get_current_stage, add_reference_to_stage
from omni.isaac.core.utils.nucleus import get_assets_root_path
from omni.isaac.core.objects import DynamicSphere
from omni.isaac.cloner import GridCloner

# create the world
world = World(stage_units_in_meters=1.0, physics_prim_path="/physicsScene", backend="numpy")

assets_root_path = get_assets_root_path()
if assets_root_path is None:
    carb.log_error("Could not find Isaac Sim assets folder, closing app..")
    simulation_app.close()
usd_path = assets_root_path + "/Isaac/Environments/Grid/default_environment.usd"
add_reference_to_stage(usd_path=usd_path, prim_path="/World/defaultGroundPlane")

# set up grid cloner
cloner = GridCloner(spacing=1.5)
cloner.define_base_env("/World/envs")
define_prim("/World/envs/env_0")

# set up the first environment
DynamicSphere(prim_path="/World/envs/env_0/object", radius=0.1, position=np.array([0.75, 0.0, 0.2]))
add_reference_to_stage(
    usd_path=assets_root_path + "/Isaac/Robots/Franka/franka.usd", prim_path="/World/envs/env_0/franka"
)

# clone environments
num_envs = 1
prim_paths = cloner.generate_paths("/World/envs/env", num_envs)
env_pos = cloner.clone(source_prim_path="/World/envs/env_0", prim_paths=prim_paths)

# creates the views and set up world
object_view = RigidPrimView(prim_paths_expr="/World/envs/*/object", name="object_view")
franka_view = ArticulationView(prim_paths_expr="/World/envs/*/franka", name="franka_view")
world.scene.add(object_view)
world.scene.add(franka_view)
world.reset()

num_dof = franka_view.num_dof

# set up randomization with omni.replicator.isaac, imported as dr
import omni.replicator.isaac as dr
import omni.replicator.core as rep

dr.physics_view.register_simulation_context(world)
dr.physics_view.register_rigid_prim_view(object_view)
dr.physics_view.register_articulation_view(franka_view)

with dr.trigger.on_rl_frame(num_envs=num_envs):
    with dr.gate.on_interval(interval=20):
        dr.physics_view.randomize_simulation_context(
            operation="scaling", gravity=rep.distribution.uniform((1, 1, 0.0), (1, 1, 2.0))
        )
    with dr.gate.on_interval(interval=50):
        dr.physics_view.randomize_rigid_prim_view(
            view_name=object_view.name, operation="direct", force=rep.distribution.uniform((0, 0, 2.5), (0, 0, 5.0))
        )
    with dr.gate.on_interval(interval=10):
        dr.physics_view.randomize_articulation_view(
            view_name=franka_view.name,
            operation="direct",
            joint_velocities=rep.distribution.uniform(tuple([-2] * num_dof), tuple([2] * num_dof)),
        )
    with dr.gate.on_env_reset():
        dr.physics_view.randomize_rigid_prim_view(
            view_name=object_view.name,
            operation="additive",
            position=rep.distribution.normal((0.0, 0.0, 0.0), (0.2, 0.2, 0.0)),
            velocity=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
        )
        dr.physics_view.randomize_articulation_view(
            view_name=franka_view.name,
            operation="additive",
            joint_positions=rep.distribution.uniform(tuple([-0.5] * num_dof), tuple([0.5] * num_dof)),
            position=rep.distribution.normal((0.0, 0.0, 0.0), (0.2, 0.2, 0.0)),
        )

frames = 1000
camera = rep.create.camera(position=(3, 3, 3), clipping_range=(0.01, 10000.0))
#rep.set_global_seed(23)
rep.settings.set_render_pathtraced(samples_per_pixel=512)
rep.settings.carb_settings("/omni/replicator/RTSubframes", 3)
render_product = rep.create.render_product(camera, (512, 512)) 

with rep.trigger.on_frame(num_frames=frames, interval=1,  rt_subframes=3):   
        with camera:
            rep.modify.pose(   
                    position=rep.distribution.uniform((2, 2, 2), (4, 4, 4)),
                    look_at="/World/envs/env_0/franka",
                    #scale=rep.distribution.uniform(0.1, 2)
                )
# Initialize and attach writer
writer = rep.WriterRegistry.get("BasicWriter") 
output_directory = r"E:\output\_out_sdrec_1"
print("Outputting data to ", output_directory)     
writer.initialize(
        output_dir=output_directory,
        rgb=True,
    )   
writer.attach([render_product])   

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

frame_idx = 0
while simulation_app.is_running():
    if world.is_playing():
        reset_inds = list()
        if frame_idx % 200 == 0:
            # triggers reset every 200 steps
            reset_inds = np.arange(num_envs)
        dr.physics_view.step_randomization(reset_inds)
        
        # trigger replicator randomizers and data collection
        rep.orchestrator.step()
        world.step(render=True)
        frame_idx += 1

simulation_app.close()

It might be waiting in an infinite loop:

while not rep.orchestrator.get_is_started():
    simulation_app.update()

Can you comment that part out, also try adding some print statements in the simulation loop, just to make sure it is getting called:

print(f"frame_idx={frame_idx}")

@ahaidu I did the modifications.

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

frame_idx = 0
while simulation_app.is_running():
    if world.is_playing():
        reset_inds = list()
        if frame_idx % 200 == 0:
            # triggers reset every 200 steps
            reset_inds = np.arange(num_envs)
        dr.physics_view.step_randomization(reset_inds)
        print(f"frame_idx={frame_idx}")
        # trigger replicator randomizers and data collection
        rep.orchestrator.step()
        world.step(render=True)
        frame_idx += 1

simulation_app.close()

However, the script runs and generates only one image. After that, the simulation freezes at frame_idx=0. The console shows the following:

[4.909s] [ext: omni.isaac.sim.python-2022.2.1] startup
[4.911s] Simulation App Starting
[15.468s] app ready
[15.573s] RTX ready
[15.697s] Simulation App Startup Complete
Outputting data to  E:\output\_out_sdrec_1
2023-03-23 10:47:55 [19,718ms] [Warning] [carb.flatcache.plugin] UsdRelationship /Render/RenderProduct_omni_kit_widget_viewport_ViewportTexture_0.orderedVars has multiple targets, which is not supported

frame_idx=0
2023-03-23 10:47:55 [19,841ms] [Warning] [omni.hydra] Disabling DLSS Frame Generation for at least one view due to incompatible render outputs and OmniGraph postprocessing being active

More than 10 minutes have passed and the simulation has not progressed.

Sorry, I missed the flag:

if world.is_playing():

Because of world.step() the world is currently not playing. Either call world.play() each step, or try removing the flag.

Let me know how it goes.

@ahaidu Now it is working! Thank you very much!!! (In addition to the flag, I removed the random joint velocities, and I am using only random joint positions, which is my goal.)

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