How can I drop objects on a plane?

Hi, what I want to achieve with omniverse is to drop some objects on a plane. In particular what I want to do is:

  • I load some USD objects from disk
  • I create/import a plane
  • I drop the objects on the plane
  • I render only the last frame along with the labels

I managed to achieve something, but not exactly what I want.

Using replicator I managed to drop the objects (using rep.physics.collider and rep.physics.rigid_body for the physics) but I have to render all the frames (I’m using the context manager rep.trigger.on_frame). Rendering all the frames is very expensive compared to rendering just one frame.

Using isaac (I use the World object and the RigidPrimfor the physics) I managed to render the last frame (after the physics simulation) but I don’t know how to set the plane as a passive rigid body (the plane fall together with the objects).

I tried to explicitly define the physics properties (with utils.setCollider and setRigidBody of omni.physx.scripts), but the objects sometimes go through the plane, sometimes they fall on the plane.

I’m wondering if someone can help me and provide a solution or a minimal example on this problem that I’m facing.

2 Likes

Hi,
to set the plane as a static collider you should just use the utils.setCollider, do not apply the rigid body part to the plane. You can also use PhysX SDK native plane, in Create->Physics->Ground Plane
For objects falling through, I would first check your units. Make sure your metersPerUnit (Clink in the layers window on the root layer and see this value in the properties window) are matching the object sizes in your scene.
If your objects are moving with large velocity, you can either increase the simulation frequency (on a physicsScene prim - Num Simulation Steps) or you can enable CCD eventually.

Thank you, playing with physics_dt and stage_units_in_meters seems to solve the problem of the objects passing through.
Is there a way to determine the correct value for the two parameters?

I’m facing another issue: I would like to run multiple physics simulations in the same run.
I can make it work in the case of a single simulation (the physics is run just one time outside the rep.trigger.on_frame) but I can’t in the multi simulations scenario. I even tried to recreate the World at each iteration but nothing change.

This is my code:

world = World(physics_dt=dt, rendering_dt=dt, stage_units_in_meters=stage_units_in_meters)
with rep.trigger.on_frame(num_frames=num_frames):
    for obj_rep in obj_reps:
        with obj_rep:
            rep.modify.pose(
                position=rep.distribution.uniform((-0.3, -0.3, 0.2), (0.3, 0.3, 0.5)),
                rotation=rep.distribution.uniform((0.0, 0.0, 0.0), (360.0, 360.0, 360.0)),
            )
    world.reset()
    for i in range(num_steps):
        world.step(render=False, step_sim=True)

Am I doing it right? How can I achieve a multi physics simulation?

EDIT:
One strange thing I noticed in the case of a single simulation. If I randomize the poses of the objects with the following code I have to define the World object after this code:

obj_reps = []
for idx, obj_prim in enumerate(objs_prim):
    obj_rep = mesh(str(obj_prim.GetPrimPath()))
    obj_reps.append(obj_rep)

for obj_rep in obj_reps:
    with obj_rep:
        rep.modify.pose(
            position=rep.distribution.uniform((-0.3, -0.3, 0.2), (0.3, 0.3, 0.5)),
            rotation=rep.distribution.uniform((0.0, 0.0, 0.0), (360.0, 360.0, 360.0)),
        )

But if I randomize the poses of the objects with the following code I can define the World object before or after without differences:

for obj_prim in objs_prim:
    xform = UsdGeom.Xformable(obj_prim)
    transform = xform.AddTransformOp()
    mat_ = np.eye(4)
    mat_[:2, 3] = np.random.uniform(-0.3, 0.3, 2)
    mat_[2, 3] = np.random.uniform(0.2, 0.5, 1)
    mat_[:3, :3] = euler.euler2mat(*np.random.uniform(0, 2 * np.pi, 3))
    mat = Gf.Matrix4d(mat_.T.tolist())
    transform.Set(mat)

The stage units are something you have to visually fix if you dont know in what units your assets were produced. But this must match as many default values are derived from the stage units. So if the stage units are set in m, your assets must be in meters. If the stage is setup in cm your assets must be in cm.

The physics_dt that really depends on how fast your objects move and how small they are. For very small objects its recommended to make the dt smaller.

Ok I am afraid I dont know enough here. Maybe @kellyg can help to answer?

Anyway from omni.physx point of view this is achievable though simulationOwner relationship and using multiple scenes. You can check the physics multiple scenes demo. However I cant tell you how to do this using IsaacSim scripts. Hope Kelly brings more light here.

Ales

Thank you very much for the help. Where can I find the example you mentioned?

EDIT:
Anyway, just to be more clear, what I want to achieve is:

  • randomize the objects
  • drop the objects on the plane
  • render a frame
  • randomize the objects
  • drop the objects on the plane
  • render a frame
  • … and so on for N times.

So if there is a solution, even completely different from mine, I’m happy to hear it.

EDIT2:
I think I found the demo file, but when I run it with ./python.sh kit/extsPhysics/omni.physx.demos-104.1.6-5.1/omni/physxdemos/scenes/MultipleScenesDemo.py I get an error:

Traceback (most recent call last):
  File "kit/extsPhysics/omni.physx.demos-104.1.6-5.1/omni/physxdemos/scenes/MultipleScenesDemo.py", line 2, in <module>
    from omni.physx.scripts.physicsUtils import *
  File "/home/federico/.local/share/ov/pkg/isaac_sim-2022.2.0/kit/extsPhysics/omni.physx-104.1.6-5.1/omni/physx/__init__.py", line 1, in <module>
    from .bindings._physx import PhysX, PhysXUnitTests, PhysXVisualization, PhysXCooking, PhysXSceneQuery, IPhysxSimulation, IPhysxBenchmarks, IPhysxAttachment, IPhysxPropertyQuery, IPhysxReplicator
ImportError: libar.so: cannot open shared object file: No such file or directory
There was an error running python

The demo script runs as part of physics demos, it wont run standalone. You can execute it trough UI, Window->Simulation->Demos.

If you need to run this sequentially using standalone omni.physx interfaces should get you what you need, but that would be completely outside of IsaacSim. Lets see what Kelly answers is IsaacSim would give you this. Because its suited for this usecase, using native USD and omni.physx interface would allow you to do this. But it would require you to hand write a lot of python code.

Any news about the multi simulation?

Kelly was on a vacation, she should be back next week.

1 Like

Hi there, Isaac Sim makes the assumption that only one PhysicsScene is present in the stage at a time. This scene is then registered with the World, which is also a Singleton. To work with a different scene at each iteration, you may need to first clear the world using world.clear_instance(), create a new stage using omni.usd.get_context().new_stage(), then creating a new World instance. Another option if you do not need a completely fresh stage is to just clear your stage and World, then re-populated it with a new set of objects.

Thank you, I will definitely try.

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