The difference between CPU and GPU pipeline


I hope this message finds you well. I recently encountered an issue while attempting to run a robot motion implementation with a ‘gpu’ pipeline. The implementation works perfectly fine when using the CPU, but when I switch the pipeline to ‘gpu’, the robot does not move. I’m writing to seek clarification regarding the potential differences between these two approaches.

Could you please help me understand why this discrepancy might occur? I would greatly appreciate any insights or suggestions you can provide to help me resolve this issue. Below is the implementation I have been using:

    def apply_actions(self, actions):
        # Actions are velocity commands
        self.apply_base_actions(actions[:, :3]) # shape: (num_envs, num_base_joints)
        self.apply_upper_body_actions(actions[:, 3:8]) # shape: (num_envs, num_upper_body_actions)
        self.apply_gripper_actions(actions[:, 8:])

    def apply_base_actions(self, base_actions):
        jt_pos = self.robots.get_joint_positions(joint_indices=self.base_dof_idxs)
        jt_pos += base_actions * self.action_base_scale * self.dt
        self.robots.set_joint_positions(positions=jt_pos, joint_indices=self.base_dof_idxs)

    def apply_upper_body_actions(self, upper_body_actions):
        jt_pos = self.robots.get_joint_positions(joint_indices=self.upper_body_dof_idxs)
        jt_pos += upper_body_actions * self.action_arm_scale * self.dt
        self.robots.set_joint_positions(positions=jt_pos, joint_indices=self.upper_body_dof_idxs)

    def apply_gripper_actions(self, gripper_actions):
        self.gripper_indices = self.gripper_left_dof_idxs + self.gripper_right_dof_idxs
        jt_pos = self.robots.get_joint_positions(joint_indices=self.gripper_indices)
        jt_pos += gripper_actions * self.action_gripper_scale * self.dt
        self.robots.set_joint_positions(positions=jt_pos, joint_indices=self.gripper_indices)

    def modify_torso(self):
        arm_dof_pos = self.get_arms_dof_pos()
        scaled_arm_lift_pos = arm_dof_pos[:, 0] / self.arm_dof_upper[0]
        scaled_torso_lift_pos = scaled_arm_lift_pos.unsqueeze(dim=1) * self.torso_dof_upper[0]

        self.robots.set_joint_positions(positions=scaled_torso_lift_pos, joint_indices=self.torso_dof_idx)

I eagerly look forward to your response and thank you in advance for your assistance.

Best regards,


The previous issue has been resolved. It was simply due to calling the set_joint_positions function multiple times within a single loop, which resulted in overwriting the values.

However, I have encountered another issue related to the behavior difference between the CPU pipeline and the GPU pipeline.
I am trying to recreate the Factory environment using the reference of the OmniIsaacGymEnvs Factory with a different robot. In the process of resetting the environment, when I use set_joint_positions to move the robot to its initial pose in the ArticulationView, the robot disappears inexplicably.
This issue does not occur when the pipeline is set to CPU, and the robot is properly initialized. However, using the CPU pipeline prevents me from simulating the SDF, which is necessary for replicating the Factory environment.

After executing the following code, the robot disappears somewhere:

def apply_actions(self, actions):
    # Actions are velocity commands
    jt_pos = self.robots.get_joint_positions(joint_indices=self.combined_dof_idxs)
    jt_pos += actions * self.action_arm_scale * self.dt

    # Modify torso value
    arm_dof_pos = self.get_arms_dof_pos()
    scaled_arm_lift_pos = arm_dof_pos[:, 0] / self.arm_dof_upper[0]
    scaled_torso_lift_pos = scaled_arm_lift_pos * self.torso_dof_upper[0]
    jt_pos[:, 3] = scaled_torso_lift_pos

    # Apply modified action
    self.robots.set_joint_positions(positions=jt_pos, joint_indices=self.combined_dof_idxs)
    SimulationContext.step(self._env._world, render=True)

Before calling it.

After calling it.

In this image, the robot and the table appear to overlap, so I initially thought that the robot might be getting displaced to an unintended location due to contact. However, even after removing the table, the same issue continues to occur.

And here is the image when running with the CPU pipeline.
Before calling it.

After calling it.

Best regards,

Similar issues seem to have been reported for IsaacSim 2022.2.0 as well.

Hi there, thanks for reporting the issue. Could you validate that the joint positions being set are within the dof limit constraints? Sometimes, undesired behaviours can occur when the states being set are beyond the limits. Otherwise, if it’s possible to provide a repro case, we can look into it. If it’s a similar issue as the referenced post, hopefully it was also fixed and will be available with the new release coming up.