Moving Robot

May I know if is it possible to move a block (sny object) directly without choosing a driver?
For example, I don’t care what is going on behind the scene, I just want my block to move with
linear velocity = 3m/s or angular velocity = 3/rad.

Thank you.

Hi,
you can use directly USD and set the linear and angular velocity for the RigidBodies:

Regards,
Ales

Thank you so much!
But I am not really familiar with USD and reading usda files.
If I may, could you please give me a simple code snippet?

Thank you!

Sure, you need something like this:

from pxr import Gf, UsdPhysics, Usd, UsdGeom
import omni.usd

stage = omni.usd.get_context().get_stage()
rigid_body_api = UsdPhysics.RigidBodyAPI.Get(stage, "/World/yourRigidBodyPath")
if rigid_body_api:
    vel = Gf.Vec3f(0,0,0)
    rigid_body_api.GetVelocityAttr().Set(vel)
    rigid_body_api.GetAngularVelocityAttr().Set(vel)
1 Like

Thank you so much for the prompt reply!
Sorry, one more question.
Is it possible to treat a whole robot as one body and move it by the method you described?

Actually, what I want to do is moving a robot rather than a rigid body.
If yes, how do I do it?

And, UsdPhysics seems to be a really powerful tool. May I know if you know where I can find its docs? I could not find it in the Issac Sim docs.

Thank you!

You would have to apply the velocity to the root body, root body is in the center of the bodies graph that is constructed by the rigid bodies and joints that connect them.
If you want to control where the root link should be you can set the articulation root API to the body directly, otherwise a center of the graph is picked.

You can check the doxygen doc:
http://omniverse-docs.s3-website-us-east-1.amazonaws.com/omni_usd_schema_physics/104.2/index.html

Hi, I have a question, I tried your method. But the problem is, I cannot find any components that can be articulation root (via GUI, the option just does not appear for all the components, links, joints and etc.). I am using the urdf file and it is automatically converted to USD by Issac sim.

May I know what should I do? Or any other suggested method?

Thank you.

Yes, you can use the inspector to see where the root is created.
I have created a small video to show how to do that:

  1. Enable the physics authoring toolbar (Window->Simulation->Physics)
  2. Select the articulation top prim - UsdPhysicsArticulationRoot should be there, typically on the top level prim
  3. Enable the inspector in the setting icon
  4. Switch the view to body/joint/material
  5. You should see the articulation and below the first link - thats the root link, you should apply the velocity to that link

Hope that helps,
Ales

Thank you so much, it is working!

However, I am facing new problems:

  1. The root found by the inspector isn’t really making sense, is it possible to change the root easily?

  2. The frame of the root isn’t moving along the movement of the robot. For example (see the video), when I rotate the robot. I was hoping the frame could move along, but it did not. So, when I commanded the robot to move forward, it did move but wasn’t “going forward”, but forward to the fixed x-axis direction. Is there anything I can do o fix this?

Thank you.

Yes, if you want to control where the root link is created then remove the articulation root from some of the top xform and move it to the body where you want to have the root link.
This is described here:

So setting the articulation root on the body makes that body the root link.

In the video I see angular velocity added, the velocities should be applied in world space.

Regards,
Ales

Thank you so much for the detailed answer!

However, changing the root link is just a minor problem. The frame problem is the one that makes me really frustrated. I describe my problem more specifically in the figure below.

Hmm ok then I think we need to go back to square one and instead of setting the velocity you should set forces, so that the velocity set does not override the solver values.

What I would suggest then in this case is to select the root link - rigid body, right click Add->Physics->Force, then apply the force/torque that you need from the python script.

You can also apply the forceAPI from a python script doing something like this:

forceApi = PhysxSchema.PhysxForceAPI.Apply(xform.GetPrim())        
forceAttr = forceApi.GetForceAttr()
torqueAttr = forceApi.GetTorqueAttr()
forceEnabledAttr = forceApi.GetForceEnabledAttr()
forceAttr.Set(Gf.Vec3f(1.0))
torqueAttr.Set(Gf.Vec3f(1.0))

So you can control through the force enabled if the force should be applied and with the force/torque attributes the values that should be applied.
For more details please see: PhysxSchemaPhysxForceAPI Class Reference

Hope this helps to solve the problem.
Regards,
Ales

Hmm… My apologies for the confusing question.

Please allow me to rephrase my question.
What I want to do is to apply my velocity to the center of mass frame, not the world frame.’

Look at the video I posted earlier, the velocity is applied to the world frame, not the center of mass frame.

Is there any method for this?

Thank you.

Yes, but not directly, indirectly by using the force as noted above, because the force is applied to COM, while velocity is in body world frame.

I see, but my ultimate goal is to move the robot through velocity, not force.
Is it possible to convert it to velocity?

No velocity cant be set directly through the ForceAPI, you can set it to either Force mode or Acceleration mode.

I summoned a colleague to check on this one too and maybe you actually want the velocity to be applied in a local space? In that case you can check the local space velocities check box maybe and thats what you need?

image

Thank you so much!

I tried this before.
It actually does not make any difference. After checking this option, the behavior of the robot is still the same.

I tried it in the script editor.

Ok then thats actually I think a bug in the integration, I will fill a Jira ticket, looking at the code its not doing what it suppose to do.
But in this case you can translate your local velocity by the body vector or not?

This is the transform from local to world:

        pxr::UsdGeomXform xform(objectRec.mPrim);
        const pxr::GfMatrix4d localToWorld = xform.ComputeLocalToWorldTransform(pxr::UsdTimeCode::Default());
        const pxr::GfTransform tr(localToWorld);
        const pxr::GfRotation rot(tr.GetRotation());
        const pxr::GfVec3f scale(tr.GetScale());

        data = rot.TransformDir(data);
        data = GfCompMult(scale, data);

So basically doing this and setting this velocity should get you there.

Thank you so much for the follow-up and the solution.

I am sorry, I do not really understand the code you provided.
If I may, could you provide me with a simple code snippet?

Thank you so much.