Inverse Kinematics has different results on the CPU and GPU [full MWE provided]

I am testing Inverse Kinematics code and I notice that there is a discrepancy between CPU and GPU mode. Here is a full minimum working example on a straightforward IK problem.

Installation and Setup

I’m using Ubuntu 18.04 with an NVIDIA 3090 GPU. I create a conda environment following the Isaac Gym installation instructions. I’m using version 1.0rc4 for isaacgym.

To get all of the data files and the python script use this zip file: MWE_UR5_IK.zip - Google Drive This will contain everything you need, including the script (UR5_IK.py). Unzip it and you should see:

(rlgpu) seita@machine:~/MWE_UR5_IK$ ls -lh 
total 20K
drwxrwxr-x 3 seita seita 4.0K Nov 28 14:06 assets
-rw-rw-r-- 1 seita seita  14K Nov 28 14:06 UR5_IK.py
(rlgpu) seita@machine:~/MWE_UR5_IK$ ls -lh assets/
total 16K
drwxrwxr-x 2 seita seita 4.0K Nov 28 14:06 meshes
-rw-rw-r-- 1 seita seita  12K Nov 28 14:06 ur5.urdf
(rlgpu) seita@machine:~/MWE_UR5_IK$ ls -lh assets/meshes/
total 8.8M
-rw-rw-r-- 1 seita seita 153K Nov 28 14:06 base.dae
-rw-rw-r-- 1 seita seita  29K Nov 28 14:06 base.stl
-rw-rw-r-- 1 seita seita 2.1M Nov 28 14:06 ee3_coarse_edited_.stl
-rw-rw-r-- 1 seita seita 1.5M Nov 28 14:06 forearm.dae
-rw-rw-r-- 1 seita seita  52K Nov 28 14:06 forearm.stl
-rw-rw-r-- 1 seita seita 988K Nov 28 14:06 shoulder.dae
-rw-rw-r-- 1 seita seita  33K Nov 28 14:06 shoulder.stl
-rw-rw-r-- 1 seita seita 2.0M Nov 28 14:06 upperarm.dae
-rw-rw-r-- 1 seita seita  58K Nov 28 14:06 upperarm.stl
-rw-rw-r-- 1 seita seita 931K Nov 28 14:06 wrist1.dae
-rw-rw-r-- 1 seita seita  35K Nov 28 14:06 wrist1.stl
-rw-rw-r-- 1 seita seita 929K Nov 28 14:06 wrist2.dae
-rw-rw-r-- 1 seita seita  35K Nov 28 14:06 wrist2.stl
-rw-rw-r-- 1 seita seita 125K Nov 28 14:06 wrist3.dae
-rw-rw-r-- 1 seita seita  22K Nov 28 14:06 wrist3.stl
(rlgpu) seita@machine:~/MWE_UR5_IK$ 

The python script is about 340 lines, though a lot is for boiler plate code and comments. The summary is that we have a UR5 robot on a linear slider, and I create two spheres (with no collisions for both) one to represent the tip of the UR5 end-effector, and the other to represent the target. The objective is to use IK so that the robot’s EE tip (yellow sphere) reaches the target (blue sphere). We also enforce an orientation so that IK should make the EE tip point upwards.

The Inverse Kinematics code is straight from the example provided in Isaac Gym when I download it: ~/isaacgym/python/examples/franka_cube_ik_osc.py which uses inverse kinematics control with Jacobian matrices and damped least squares. I copied that IK code into the MWE script I linked to (see the .zip file from earlier).

Test CPU vs GPU mode

Then test CPU and GPU mode:

python UR5_IK.py --pipeline=cpu
python UR5_IK.py --pipeline=gpu

Observe that the results are different, with CPU mode resulting in better performance compared to GPU mode.

On the CPU the yellow/blue target spheres almost coincide (good) and this is what usually happens:

On the GPU, however, the spheres do not coincide.

I am not sure why this happens. IK will produce a recommended change in the DOF position targets while the robot is in the steady state on the GPU mode, but for some reason the robot isn’t moving or applying those DOFs. (Of course the bigger issue is why CPU and GPU performance differ at all.)

A few follow-up points:

  • CPU mode will print out:
    Physics Engine: PhysX
    Physics Device: cpu
    GPU Pipeline: disabled
    
  • GPU mode will print out:
    +++ Using GPU PhysX
    Physics Engine: PhysX
    Physics Device: cuda:0
    GPU Pipeline: enabled
    
  • From the above, it seems like CPU and GPU modes are using CPU and GPU versions of PhysX, respectively, so that could be one difference?

A possibly relevant thread:

Thanks to anyone who might be able to offer advice.

1 Like

Hello,
I am just wondering if anyone had the chance to take a look at this?
Thanks