Hello!
I’m currently trying to create synthetic data containing a deformable body acting as a slipsheet between different layers of cases on a pallet.
I’ve managed to get the physics working during the replicator randomization thanks to this post (https://forums.developer.nvidia.com/t/trigger-randomization/254170/8), but I’m now running into the problem that I need to reset my deformable before the next data point can be captured.
I want to randomize the position of the sheet and afterwards apply the physics again. Currently I’m only able to start the physics simulation once in the beginning and then randomize the texture and position afterwards.
So if I randomize the position of my sheet the result is sadly not usable. Ideally I want the Sheet to lay on the cases below and bend in the front without clipping into the cases.
Is there any way to reset the physics of the sheet through the replicator without instantiating a new slipsheet object and deleting the old one?
Here’s my code:
import omni
import omni.usd
import omni.kit as kit
import numpy as np
import os
import omni.replicator.core as rep
from PIL import Image
from pxr import UsdPhysics
from omni.physx.scripts import physicsUtils, deformableUtils
from omni.isaac.core.objects.ground_plane import GroundPlane
####################
# Create Functions #
####################
def create_materials():
omni.kit.commands.execute(
"CreateMdlMaterialPrimCommand",
mtl_url="omniverse://localhost/NVIDIA/Materials/vMaterials_2/Paper/Cardboard_Low_Quality.mdl",
mtl_name="Cardboard_Low_Quality",
mtl_path="/Materials/CardboardRough"
)
omni.kit.commands.execute(
"CreateMdlMaterialPrimCommand",
mtl_url="omniverse://localhost/NVIDIA/Materials/Base/Wall_Board/MDF.mdl",
mtl_name="MDF",
mtl_path="/Materials/MDF"
)
def create_cube(id, translation, scale):
cube_prim_path = "/World/Cube_" + str(id)
cube_object = kit.primitive.mesh.CreateMeshPrimCommand(
prim_type="Cube",
object_origin=(0,0,0),
prim_path=cube_prim_path,
u_verts_scale=1,
v_verts_scale=1
)
cube_object.do()
cube_prim =stage.GetPrimAtPath(cube_prim_path)
cube_prim.GetAttribute('xformOp:translate').Set(translation)
cube_prim.GetAttribute('xformOp:scale').Set(scale)
UsdPhysics.CollisionAPI.Apply(cube_prim)
omni.kit.commands.execute('BindMaterialCommand',
prim_path=cube_prim_path,
material_path="/Materials/CardboardRough",
strength='weakerThanDescendants')
##########
# Basics #
##########
deformable = True
stage = omni.usd.get_context().get_stage()
default_prim_path = "/World"
cube_translation_list = [
(0, 0, 0.075),
(0, 0.205, 0.075),
(0, -0.205, 0.075),
(-0.255, 0, 0.075),
(-0.255, 0.205, 0.075),
(-0.255, -0.205, 0.075),
(0.255, 0, 0.075),
(0.255, 0.205, 0.075),
(0.255, -0.205, 0.075),
# (0.51, 0.205, 0.075),
(-0.255, 0.205, 0.24),
(-0.255, 0, 0.24),
]
cube_scale = (0.25, 0.2, 0.15)
create_materials()
for id, trans in enumerate(cube_translation_list):
create_cube(id=id, translation=trans, scale=cube_scale)
GroundPlane(prim_path="/World/groundPlane", size=10, color=np.array([0.5, 0.5, 0.5]))
##############
# Deformable #
##############
cube_prim_path = "/World/Slipsheets"
cube_u_verts_scale = 30
cube_v_verts_scale = 30
cube_w_verts_scale = 2
simulation_resolution = 30
slipsheet_width = 0.95
slipsheet_depth = 0.55
slipsheet_height = 0.003
slipsheet_volume_m3 = slipsheet_width * slipsheet_depth * slipsheet_height
paper_density_kg_per_m3 = 700
weight_slipsheet = paper_density_kg_per_m3 * slipsheet_volume_m3
slipsheet_translation_1 = (0.13, 0, 0.152)
slipsheet_translation_2 = (0.13, 0, 0.35)
cube_object_1 = kit.primitive.mesh.CreateMeshPrimCommand(
prim_type="Cube",
object_origin=(0,0,0),
prim_path=os.path.join(cube_prim_path,"cube_1"),
u_verts_scale=cube_u_verts_scale,
v_verts_scale=cube_v_verts_scale,
w_verts_scale=cube_w_verts_scale
)
cube_object_1.do()
cube_prim_1 = stage.GetPrimAtPath(os.path.join(cube_prim_path,"cube_1"))
cube_prim_1.GetAttribute('xformOp:translate').Set(slipsheet_translation_1)
cube_prim_1.GetAttribute('xformOp:scale').Set((slipsheet_width, slipsheet_depth, 0.002))
particle_system_path = "/World/ParticleSystem"
if deformable:
deformableUtils.add_physx_deformable_body(
stage,
cube_prim_1.GetPath(),
collision_simplification=True,
simulation_hexahedral_resolution=simulation_resolution,
self_collision=True,
solver_position_iteration_count=32,
)
deformable_material_path = omni.usd.get_stage_next_free_path(stage, default_prim_path + "/deformableBodyMaterial", True)
deformableUtils.add_deformable_body_material(
stage,
deformable_material_path,
youngs_modulus=1000000.0,
poissons_ratio=0.33,
damping_scale=0.0,
dynamic_friction=5.0,
elasticity_damping=0.0003
)
physicsUtils.add_physics_material_to_prim(stage, cube_prim_1.GetPrim(), deformable_material_path)
cube_prim_1.GetAttribute('physxCollision:contactOffset').Set(0.001)
cube_prim_1.GetAttribute('physxCollision:restOffset').Set(0.00099)
massApi_1 = UsdPhysics.MassAPI.Apply(cube_prim_1.GetPrim())
massApi_1.GetMassAttr().Set(weight_slipsheet)
class DummyWriter(rep.Writer):
def __init__(self,
msg,
output_dir,
rgb_save):
self._output_dir = output_dir
self._backend = rep.BackendDispatch({"paths": {"out_dir": output_dir}})
self._image_output_format = "png"
self._frame_id = 0
self.annotators = []
self.rgb_save = rgb_save
self.annotators.append(rep.AnnotatorRegistry.get_annotator("rgb"))
self.msg = msg
def write(self, data):
# print(self.msg)
img = Image.fromarray(data["rgb"])
if self.rgb_save:
self.save_visualization(img, data)
self._frame_id += 1
def save_visualization(self, img, data):
# rgb
image_name = "rgb_{:04d}.png".format(self._frame_id)
self._backend.write_image(image_name, img)
def move_slipsheet():
slipsheet = rep.get.prims(path_pattern=os.path.join(cube_prim_path,"cube_1"))
with slipsheet:
rep.randomizer.color(colors=rep.distribution.uniform((0,0,0), (1,1,1)))
return slipsheet.node
with rep.new_layer():
rep.randomizer.register(move_slipsheet)
camera = rep.create.camera(look_at=(0,0,0), position=(2,0.5,2))
rp = rep.create.render_product(camera, (1024, 1024))
# Writer that writes every frame
writer = DummyWriter(msg="STEPPING", output_dir="./output", rgb_save=False)
writer.attach(rp)
# Writer that writes every 24 frames
writer = DummyWriter(msg="WRITING", output_dir="./output", rgb_save=True)
writer.attach(rp, trigger=rep.trigger.on_frame(max_execs=10, interval=30))
# Play timeline with replicator start
rep.orchestrator.set_capture_on_play(True)
with rep.trigger.on_frame(max_execs=10, interval=30):
rep.randomizer.move_slipsheet()
# Run orchestrator
rep.orchestrator.run()
Any help is greatly appreciated!