code: def _get_observation(self):
          
          di = super()._get_observation()
          # camera observations
          if self.use_camera_obs:
              camera_obs = self.sim.render(
                  camera_name=self.camera_name,
                  width=self.camera_width,
                  height=self.camera_height,
                  depth=self.camera_depth,
              )
              if self.camera_depth:
                  di["image"], di["depth"] = camera_obs
              else:
                  di["image"] = camera_obs
  
          # low-level object information
          if self.use_object_obs:
              # position and rotation of object
              cube_pos = np.array(self.sim.data.body_xpos[self.cube_body_id])
              cube_quat = convert_quat(
                  np.array(self.sim.data.body_xquat[self.cube_body_id]), to="xyzw"
              )
              di["cube_pos"] = cube_pos
              di["cube_quat"] = cube_quat
  
              gripper_site_pos = np.array(self.sim.data.site_xpos[self.eef_site_id])
              di["gripper_to_cube"] = gripper_site_pos - cube_pos
  
              di["object-state"] = np.concatenate(
                  [cube_pos, cube_quat, di["gripper_to_cube"]]
              )
  
          return di
docs: Returns an OrderedDict containing observations [(name_string, np.array), ...].
  
          Important keys:
              robot-state: contains robot-centric information.
              object-state: requires @self.use_object_obs to be True.
                  contains object-centric information.
              image: requires @self.use_camera_obs to be True.
                  contains a rendered frame from the simulation.
              depth: requires @self.use_camera_obs and @self.camera_depth to be True.
                  contains a rendered depth map from the simulation