Forces and Torques in Isaac

Hey all,

I am trying to port the uuv_gazebo_plugins from Gazebo to Isaac. These plugins allow to simulate ROVs, and USVs in Gazebo, and I’d like to do the same in Isaac. I ported all the code from c++ to python, and I need to write some function to do the following:

  • Apply Forces
  • Apply Torques

To apply forces there are at least two methods:

  • Using dynamic_control_ one can use apply_body_force. The issue with this method is that it only applies a force at the center of the object, and I could not figure out how to apply the force at specific position relative to that object.
  • The other method is apply_force_at_pos from the Physx python bindings. This one works as expected.

Then to apply torques I could not find any methods to do it. I think IsaacGym has ones, I know Physx has an apply torque function, and actually quite a lot more of apply force functions.

Are there any methods to apply torques available in Isaac? If I have to use my own it’s a lot of calculations…

def AddRelativeTorque(PhysXIFace, prim_path, torque, dist=100):
    torque_norm = np.linalg.norm(torque)
    torque_normalized = torque/torque_norm
    # Projects torque to world frame
    transform = PhysXIFace.get_rigidbody_transformation(prim_path)
    R = Quaternion2RotationMatrix(transform['quaternion'])
    torque_normalized = np.matmul(R,torque_normalized)
    # Make virtual vector
    idx = np.argmin(torque)
    v = np.zeros([3])
    v[idx] = 1.0
    # Get two orthogonal vectors to the torque vector
    w = np.cross(torque_normalized, v)
    w21 = np.cross(torque_normalized, w)
    w22 = -w21
    f1_dir = np.cross(torque_normalized,w21)
    f2_dir = -np.cross(torque_normalized,w22)
    p1 = w21 * dist
    p2 = w22 * dist
    # Apply forces at the position of the object
    PhysXIFace.apply_force_at_pos(prim_path,f1_dir*torque_norm/2,p1 + np.array(transform['position']))
    PhysXIFace.apply_force_at_pos(prim_path,f2_dir*torque_norm/2,p2 + np.array(transform['position']))

Thanks in advance,

Best,

Antoine

Filed an issue, apply_body_force from DC should be able to handle this so you don’t have to compute the transforms manually

@antoine.richard your feedback has been included in the latest release!
In particular, you’ll find that:

  • DC’s apply_body_force method has now a bool argument to define if coordinates are local or global.
  • There is a new apply_body_torque method, also with the same bool argument as the force method

Thanks a lot!

@antoine.richard let me know if you find any issues, or if something doesn’t work as desired, we have a bugfix release in a few weeks and can get things fixed for that if needed

From my tests it seems to be working fine. Just to make sure I understood correctly, when set to True, the flag applies the force/torque in the world frame, when set to False it applies the force/torque in the body frame. The arguments in the dynamic control API are still a bit cryptic to me.

apply_body_force(arg0,arg1,arg2,arg3)

  • arg0 (int) dynamic control handle
  • arg1 (carb3) the force to be applied to the object
  • arg2 (carb3) the position where that force will be applied
  • arg3 (bool) False to apply the force in the body frame, True to apply in world the frame

apply_body_torque(arg0,arg1,arg2)

  • arg0 (int) dynamic control handle
  • arg1 (carb3) the torque to be applied to the object
  • arg3 (bool) False to apply the torque in the body frame, True to apply in world the frame

Correct.

I agree they are cryptic, pybind11 isn’t able to name arguments so autogenerated docstring pick them up. Have to name each one manually, will see if its possible to fix without too much work…