code: def reward(self, action=None):
          
          reward = 0.
  
          # sparse completion reward
          if self._check_success():
              reward = 1.0
  
          # use a shaping reward
          if self.reward_shaping:
  
              # reaching reward
              cube_pos = self.sim.data.body_xpos[self.cube_body_id]
              gripper_site_pos = self.sim.data.site_xpos[self.eef_site_id]
              dist = np.linalg.norm(gripper_site_pos - cube_pos)
              reaching_reward = 1 - np.tanh(10.0 * dist)
              reward += reaching_reward
  
              # grasping reward
              touch_left_finger = False
              touch_right_finger = False
              for i in range(self.sim.data.ncon):
                  c = self.sim.data.contact[i]
                  if c.geom1 in self.l_finger_geom_ids and c.geom2 == self.cube_geom_id:
                      touch_left_finger = True
                  if c.geom1 == self.cube_geom_id and c.geom2 in self.l_finger_geom_ids:
                      touch_left_finger = True
                  if c.geom1 in self.r_finger_geom_ids and c.geom2 == self.cube_geom_id:
                      touch_right_finger = True
                  if c.geom1 == self.cube_geom_id and c.geom2 in self.r_finger_geom_ids:
                      touch_right_finger = True
              if touch_left_finger and touch_right_finger:
                  reward += 0.25
  
          return reward
docs: Reward function for the task.
  
          The dense reward has three components.
  
              Reaching: in [0, 1], to encourage the arm to reach the cube
              Grasping: in {0, 0.25}, non-zero if arm is grasping the cube
              Lifting: in {0, 1}, non-zero if arm has lifted the cube
  
          The sparse reward only consists of the lifting component.
  
          Args:
              action (np array): unused for this task
  
          Returns:
              reward (float): the reward