Unexpected Spinning Behavior with Fixed Gripper Using Custom USD File

Isaac Sim Version

[√] 4.5.0

Operating System

[√] Windows 11
[√] Windows 10

Topic Description

Detailed Description

Hi everyone,

I’m trying to achieve an effect where a gripper remains fixed at a point in space, but can freely rotate around the X, Y, and Z axes—essentially, a 3-DoF rotational joint with no translation.

I’m using an external USD file for the gripper, which has the following structure:

-gripper               # Xform
--Looks                # Scope
----DefaultMaterial    # Material
------DefaultMaterial  # Shader
--PARTassembly         # Mesh Group
----PARTassembly       # Mesh

For reference, I tested my setup using a DynamicCone, where the tip of the cone is fixed in mid-air and it can rotate freely—this worked exactly as expected.

# Add ConeGripper
gripper = DynamicCone(
    prim_path="/World/Gripper",
    radius=0.5,
    height=1.0,
    color=np.array([0, 1.0, 0.0]),
    mass=1.0
)
# set the initial poses of the gripper
gripper.set_world_pose(position=np.array([0, 0, 4])/ get_stage_units(), orientation=np.array([1., 0., 0., 0.]))

anchor =  DynamicCuboid(
        prim_path="/World/anchor",
        name="anchor",
        position=np.array([0, 0, 5]),
        scale=np.array([1, 1, 1]),
        color=np.array([0, 0, 1.0]),
    )
anchor.disable_rigid_body_physics()
anchor.set_visibility(visible=False)

from pxr import UsdPhysics, Gf

def fix_to_ground(stage, joint_path, prim_path, anchor_pos):
    # D6 fixed joint
    d6FixedJoint = UsdPhysics.Joint.Define(stage, joint_path)
    d6FixedJoint.CreateBody0Rel().SetTargets(["/World/anchor"])
    d6FixedJoint.CreateBody1Rel().SetTargets([prim_path])
    d6FixedJoint.CreateLocalPos0Attr().Set(anchor_pos)
    d6FixedJoint.CreateLocalRot0Attr().Set(Gf.Quatf(1.0, Gf.Vec3f(0, 0, 0)))
    d6FixedJoint.CreateLocalPos1Attr().Set(Gf.Vec3f(0, 0, 0.5))
    d6FixedJoint.CreateLocalRot1Attr().Set(Gf.Quatf(1.0, Gf.Vec3f(0, 0, 0)))
    # lock all DOF (lock - low is greater than high)
    d6Prim = stage.GetPrimAtPath(joint_path)
    limitAPI = UsdPhysics.LimitAPI.Apply(d6Prim, "transX")
    limitAPI.CreateLowAttr(1.0)
    limitAPI.CreateHighAttr(-1.0)
    limitAPI = UsdPhysics.LimitAPI.Apply(d6Prim, "transY")
    limitAPI.CreateLowAttr(1.0)
    limitAPI.CreateHighAttr(-1.0)
    limitAPI = UsdPhysics.LimitAPI.Apply(d6Prim, "transZ")
    limitAPI.CreateLowAttr(1.0)
    limitAPI.CreateHighAttr(-1.0)

fix_to_ground(stage, joint_path="/World/Gripper_anchor", prim_path="/World/Gripper", anchor_pos=Gf.Vec3f(0, 0, 0))

However, when I apply the same setup/code to my gripper model, it behaves incorrectly: the gripper spins uncontrollably and doesn’t stay oriented as intended.

# load gripper model
gripper_path = "G:/gripper.usd".replace("\\", "/").strip()
gripper_prim_path = "/World/gripper"
add_reference_to_stage(usd_path=gripper_path, prim_path=gripper_prim_path)
my_world.scene.add(
    XFormPrim(
        prim_paths_expr=gripper_prim_path,
        name="gripper",
        positions=np.array([[0,0,0.5]]),
        #translations=np.array([[0,0,1]]),
        orientations=np.array([[0.70710678, 0.70710678, 0, 0]]),  
        scales=np.array([[0.001, 0.001, 0.001]])
        )
)
gripper_rigid_prim = RigidPrim("/World/gripper")
gripper_rigid_prim.set_masses(np.full(1, 1)) 

gripper_geometry_prim = GeometryPrim("/World/gripper/PARTassembly/PARTassembly")
gripper_geometry_prim.apply_collision_apis()
gripper_geometry_prim.set_collision_approximations(["sdf"])



from pxr import UsdPhysics, Gf
def fix_gripper_to_anchor(stage, joint_path, prim_path, anchor_pos):
    
    # D6 fixed joint
    d6FixedJoint = UsdPhysics.Joint.Define(stage, joint_path)
    d6FixedJoint.CreateBody0Rel().SetTargets(["/World/anchor"])
    d6FixedJoint.CreateBody1Rel().SetTargets([prim_path])
    d6FixedJoint.CreateLocalPos0Attr().Set(Gf.Vec3f(0, 0, 0))  # Set to 0,0,0 because we want anchor to be at the center of the cuboid
    d6FixedJoint.CreateLocalRot0Attr().Set(Gf.Quatf(1.0, Gf.Vec3f(0, 0, 0)))
    d6FixedJoint.CreateLocalPos1Attr().Set(Gf.Vec3f(0, 0, 0))
    d6FixedJoint.CreateLocalRot1Attr().Set(Gf.Quatf(1.0, Gf.Vec3f(0, 0, 0)))
    # lock all DOF (lock - low is greater than high)
    d6Prim = stage.GetPrimAtPath(joint_path)
    limitAPI = UsdPhysics.LimitAPI.Apply(d6Prim, "transX")
    limitAPI.CreateLowAttr(1.0)
    limitAPI.CreateHighAttr(-1.0)
    limitAPI = UsdPhysics.LimitAPI.Apply(d6Prim, "transY")
    limitAPI.CreateLowAttr(1.0)
    limitAPI.CreateHighAttr(-1.0)
    limitAPI = UsdPhysics.LimitAPI.Apply(d6Prim, "transZ")
    limitAPI.CreateLowAttr(1.0)
    limitAPI.CreateHighAttr(-1.0)

fix_gripper_to_anchor(stage, joint_path="/World/gripper_anchor", prim_path="/World/gripper/PARTassembly", anchor_pos=Gf.Vec3f(0, 0, 0))

Has anyone encountered similar behavior with custom USD assets or mesh-based models? Could there be something in the USD hierarchy or mesh configuration that might cause this instability?

Any guidance would be greatly appreciated!

Thanks in advance.

Could you check if this issue is caused by the joint constraints being applied to /World/gripper/PARTassembly instead of /World/gripper (the RigidPrim)?

Hi @terence0tan, Are you still having the same issue? It seems to be like the cause is due to the gripper having very small moment of inertia around the rotational point, causing it to move with a very high angular velocity. What is the inertia parameters of your gripper?

Try also to increase the step rate of the physics simulation. To do that go to physicsScene>Properties>Time Steps Per Second. Make it 240 or 360, it may help the physics solver better handle the high velocities.

Hello!

We noticed that this topic hasn’t received any recent responses, so we are closing it for now to help keep the forum organized.

If you’re still experiencing this issue or have additional questions, please feel free to create a new topic with updated details. When doing so, we recommend mentioning or linking to this original topic in your new post—this helps provide context and makes it easier for others to assist you.

Thank you for being part of the NVIDIA Isaac Sim community.

Best regards,
The NVIDIA Isaac Sim Forum Team