How to get Replicator to randomize a pivot transform

I want to randomize the hinge angles of the doors in my USD stage. This environment was built on Revit and converted to USD, so I had to fix all transforms by adding pivot transforms as suggested in this topic.

I was hoping to be able to simply move the doors’ pivot transforms to their hinged side and then use rep.modify.pose() to change the doors’ hinge angles but instead of rotating them around their pivot transforms this rotates them around their world transforms that were left at the origin.

Pivot I added:

Desired effect:

What I got instead, door mesh rotates around world origin:

I’ve also tried adding the pivot’s coordinates as an argument in the test code :

  def register_change_door_pose():
      def change_door_pose():
          with door_hinge:
                   pivot=(-0.0058623552322387695, -9.94433069229126, 1.1625000145286322)
              return door_hinge.node
  with rep.trigger.on_frame(num_frames=10):

but I’m getting this error message:

[Error] [omni.graph.core.plugin] /Replicator/SDGPipeline/OgnSetPivot_01: OmniGraph Error: The pivot can only be set to a xform prim, but got Mesh

How can I get this to work?

it’s just a hunch, but looks like we’ll need to append an extra xform (at the same spot as the custom pivot you had set for the door hinge) to act as the parent of the door because of the way how replicator’s pivot works(?). based on the report log, it’s limited to an xform and not a mesh (Porte_Vetro_1024351).
that said, there may be additional issues if you have more geom child prim(s) in that stack (see the other thread).

you could try merging meshes under that hiearchy and then append the xform for the roration to work, perhaps. (again, this is just me thinking outloud and in no way definitive)

I forgot to mention that I did try this as soon as the error message came up but it kept rotating it around the wrong transform, maybe I’ll give it another shot later and see if I have missed something. I’ve then tried using rep.modify.attribute() instead of rep.modify.pose() which should work but I’m having issues passing a quaternion as the new attribute value, error messages tell me I need a value of type ‘GfQuatd’ but I have no idea which classes or methods return such a type… maybe I’ll have to post this in another topic.

would this post help?

I’ve seen that topic but it wasn’t very helpful for me.

I think @Simplychenable nailed it. Just convert your 3D to quaternion

import math

angle_1 = -25
angle_2 = 25
angle_rad1 = math.radians(-25)
angle_rad2 = math.radians(25)
quat1 = Gf.Quatf(math.cos(angle_rad1/2), 0, 0, math.sin(angle_rad1/2)) # w, x, y, z
quat2 = Gf.Quatf(math.cos(angle_rad2/2), 0, 0, math.sin(angle_rad2/2)) # w, x, y, z

with door_hinge:
                   rotation=rep.distribution.uniform(quat1, quat2),
                   pivot=(-0.0058623552322387695, -9.94433069229126, 1.1625000145286322)

Note you may also need to convert the pivots into the correct type.

Just remember to move that sin function to the appropriate axis.

You could also use numpy’s euler to quat which i find pretty nice and succinct.

euler_angles = (np.radians(30), np.radians(45), np.radians(60)) # x, y, z
quat = np.quaternion(*np.quat_from_euler(euler_angles, 'sxyz'))

np is nice because you can easily apply it to an array if you end up doing rep.distribution.sequence’s. For instance if you want to have the door open in a none uniform way (it slows down as it’s almost open or closed using a spring equation for instance).

Hi @salvo.dipp Sorry for the late reply.

I think I need a bit more information here. It seems like this is a situation where you want the transform of the mesh or its parent to be at the required location of the hinge. Then from there you should be able to vary the rotation using modify pose, but only on one axis and within a range using a uniform distribution?

I saw you were discussing this on discord also, so feel free to reach out to me there.