Example #1
0
    def __init__(self, configs, simulator):
        self.sim = simulator.sim
        self.configs = configs
        self.agent = self.sim.get_agent(self.configs.COMMON.SIMULATOR.DEFAULT_AGENT_ID)

        # Depth Image processor
        self.depth_cam = DepthImgProcessor(
            subsample_pixs=1,
            depth_threshold=(0, 100),
            cfg_filename="realsense_habitat.yaml"
        )

        # Pan and tilt related vairades.
        self.pan = 0.0
        self.tilt = 0.0
    def restart_habitat(self):
        if hasattr(self, "_robot"):
            del self._robot
        backend_config = self.backend_config

        self._robot = Robot("habitat", common_config=backend_config)
        from habitat_utils import reconfigure_scene

        # adds objects to the scene, doing scene-specific configurations
        reconfigure_scene(self, backend_config["scene_path"], self.add_humans)
        from pyrobot.locobot.camera import DepthImgProcessor

        if hasattr(self, "_dip"):
            del self._dip
        self._dip = DepthImgProcessor(cfg_filename="realsense_habitat.yaml")
Example #3
0
    def restart_habitat(self):
        if hasattr(self, "_robot"):
            del self._robot
        backend_config = self.backend_config
        self._robot = Robot("habitat", common_config=backend_config)
        # todo: a bad package seems to override python logging after the line above is run.
        # So, all `logging.warn` and `logging.info` calls are failing to route
        # to STDOUT/STDERR after this.
        from habitat_utils import reconfigure_scene

        # adds objects to the scene, doing scene-specific configurations
        reconfigure_scene(self, backend_config["scene_path"])
        from pyrobot.locobot.camera import DepthImgProcessor

        if hasattr(self, "_dip"):
            del self._dip
        self._dip = DepthImgProcessor(cfg_filename="realsense_habitat.yaml")
Example #4
0
    def __init__(self, backend="locobot", backend_config=None):
        if backend == "locobot":
            base_config_dict = {"base_controller": "proportional"}
            arm_config_dict = dict(moveit_planner="ESTkConfigDefault")
            self._robot = Robot(
                backend,
                use_base=True,
                use_arm=True,
                use_camera=True,
                base_config=base_config_dict,
                arm_config=arm_config_dict,
            )

            self._dip = DepthImgProcessor()

            from grasp_samplers.grasp import Grasper

        elif backend == "habitat":
            if backend_config["physics_config"] == "DEFAULT":
                assets_path = os.path.abspath(
                    os.path.join(os.path.dirname(__file__),
                                 "../test/test_assets"))
                backend_config["physics_config"] = os.path.join(
                    assets_path, "default.phys_scene_config.json")
            print("backend_config", backend_config)
            self.backend_config = backend_config
            # we do it this way to have the ability to restart from the client at arbitrary times
            self.restart_habitat()
        else:
            raise RuntimeError("Unknown backend", backend)

        # check skfmm, skimage in installed, its necessary for slam
        self._slam = Slam(self._robot, backend)
        self._slam_step_size = 25  # step size in cm
        self._done = True
        self.backend = backend
Example #5
0
class LoCoBotCamera(object):
    """docstring for SimpleCamera"""

    def __init__(self, configs, simulator):
        self.sim = simulator.sim
        self.configs = configs
        self.agent = self.sim.get_agent(self.configs.COMMON.SIMULATOR.DEFAULT_AGENT_ID)

        # Depth Image processor
        self.depth_cam = DepthImgProcessor(
            subsample_pixs=1,
            depth_threshold=(0, 100),
            cfg_filename="realsense_habitat.yaml"
        )

        # Pan and tilt related vairades.
        self.pan = 0.0
        self.tilt = 0.0

    def get_rgb(self):
        observations = self.sim.get_sensor_observations()
        return observations["rgb"][:, :, 0:3]

    def get_depth(self):
        observations = self.sim.get_sensor_observations()
        return observations["depth"]

    def get_rgb_depth(self):
        observations = self.sim.get_sensor_observations()
        return observations["rgb"][:, :, 0:3], observations["depth"]

    def get_intrinsics(self):
        """
		Returns the instrinsic matrix of the camera

		:return: the intrinsic matrix (shape: :math:`[3, 3]`)
		:rtype: np.ndarray
		"""
        fx = self.configs['Camera.fx']
        fy = self.configs['Camera.fy']
        cx = self.configs['Camera.cx']
        cy = self.configs['Camera.cy']
        Itc = np.array([[fx, 0, cx], [0, fy, cy], [0, 0, 1]])
        return Itc

    def pix_to_3dpt(self, rs, cs, in_cam=False, initial_rotation=None):
        """
        Get the 3D points of the pixels in RGB images.

        :param rs: rows of interest in the RGB image.
                   It can be a list or 1D numpy array
                   which contains the row indices.
                   The default value is None,
                   which means all rows.
        :param cs: columns of interest in the RGB image.
                   It can be a list or 1D numpy array
                   which contains the column indices.
                   The default value is None,
                   which means all columns.
        :param in_cam: return points in camera frame,
                       otherwise, return points in base frame

        :param initial_rotation: a known initial rotation of the camera sensor
                                 to calibrate habitat origin. The default value
                                 is None which means it uses the Habitat-reported
                                 value.

        :type rs: list or np.ndarray
        :type cs: list or np.ndarray
        :type in_cam: bool

        :returns: tuple (pts, colors)

                  pts: point coordinates in world frame
                  (shape: :math:`[N, 3]`)

                  colors: rgb values for pts_in_cam
                  (shape: :math:`[N, 3]`)

        :rtype: tuple(np.ndarray, np.ndarray)
        """
        rgb_im, depth_im = self.get_rgb_depth()
        pts_in_cam = self.depth_cam.get_pix_3dpt(depth_im=depth_im, rs=rs, cs=cs)
        pts = pts_in_cam[:3, :].T

        colors = rgb_im[rs, cs].reshape(-1, 3)
        if in_cam:
            return pts, colors

        # here, points are now given in camera frame
        # the thing to do next is to transform the points from camera frame into the
        # global frame of pyrobot environment
        # This does not translate to what habitat thinks as origin,
        # because pyrobot's habitat-reference origin is `self.agent.init_state`
        # So, CAMERA frame -> HABITAT frame -> PYROBOT frame

        init_state = self.agent.initial_state # habitat - x,y,z
        cur_state = self.agent.get_state()
        cur_sensor_state = cur_state.sensor_states['rgb']
        if initial_rotation is None:
            initial_rotation = init_state.sensor_states['rgb'].rotation
        rot_init_rotation = self._rot_matrix(initial_rotation)


        ros_to_habitat_frame = np.array([[ 0.0, -1.0,  0.0],
                                         [ 0.0,  0.0,  1.0],
                                         [-1.0,  0.0,  0.0]])

        camera_to_image_frame = np.array([[1.0,  0.0,  0.0],
                                          [0.0, -1.0,  0.0],
                                          [0.0,  0.0, -1.0]])

        relative_position = cur_sensor_state.position - init_state.position
        relative_position = rot_init_rotation.T @ relative_position

        cur_rotation = self._rot_matrix(cur_sensor_state.rotation)
        cur_rotation = rot_init_rotation.T @ cur_rotation

        rot_habitat_origin_to_image_frame = cur_rotation @ camera_to_image_frame

        # now do the final transformation and return the points
        pts = np.dot(pts, rot_habitat_origin_to_image_frame.T)
        pts = pts + relative_position
        pts = ros_to_habitat_frame.T @ pts.T
        pts = pts.T
        return pts, colors


    def _rot_matrix(self, habitat_quat):
        quat_list = [habitat_quat.x, habitat_quat.y, habitat_quat.z, habitat_quat.w]
        return prutil.quat_to_rot_mat(quat_list)


    def get_current_pcd(self, in_cam=True):
        """
		Return the point cloud at current time step (one frame only)

		:param in_cam: return points in camera frame,
		               otherwise, return points in base frame

		:type in_cam: bool
		:returns: tuple (pts, colors)

		          pts: point coordinates in world frame (shape: :math:`[N, 3]`)

		          colors: rgb values for pts_in_cam (shape: :math:`[N, 3]`)
		:rtype: tuple(np.ndarray, np.ndarray)
		"""

        raise NotImplementedError

    @property
    def state(self):
        """
		Return the current pan and tilt joint angles of the robot camera.

		:return:
		        pan_tilt: A list the form [pan angle, tilt angle]
		:rtype: list
		"""
        return self.get_state()

    def get_state(self):
        """
		Return the current pan and tilt joint angles of the robot camera.

		:return:
		        pan_tilt: A list the form [pan angle, tilt angle]
		:rtype: list
		"""
        return [self.pan, self.tilt]

    def get_pan(self):
        """
		Return the current pan joint angle of the robot camera.

		:return:
		        pan: Pan joint angle
		:rtype: float
		"""
        return self.pan

    def get_tilt(self):
        """
		Return the current tilt joint angle of the robot camera.

		:return:
		        tilt: Tilt joint angle
		:rtype: float
		"""
        return self.tilt

    def set_pan(self, pan, wait=True):
        """
		Sets the pan joint angle to the specified value.

		:param pan: value to be set for pan joint
		:param wait: wait until the pan angle is set to
		             the target angle.

		:type pan: float
		:type wait: bool
		"""

        self.set_pan_tilt(pan, self.tilt)

    def set_tilt(self, tilt, wait=True):
        """
		Sets the tilt joint angle to the specified value.

		:param tilt: value to be set for the tilt joint
		:param wait: wait until the tilt angle is set to
		             the target angle.

		:type tilt: float
		:type wait: bool
		"""

        self.set_pan_tilt(self.pan, tilt)

    def _compute_relative_pose(self, pan, tilt):

        pan_link = 0.1  # length of pan link
        tilt_link = 0.1  # length of tilt link

        sensor_offset_tilt = np.asarray([0.0, 0.0, -1 * tilt_link])

        quat_cam_to_pan = habUtils.quat_from_angle_axis(
            -1 * tilt, np.asarray([1.0, 0.0, 0.0])
        )

        sensor_offset_pan = habUtils.quat_rotate_vector(
            quat_cam_to_pan, sensor_offset_tilt
        )
        sensor_offset_pan += np.asarray([0.0, pan_link, 0.0])

        quat_pan_to_base = habUtils.quat_from_angle_axis(
            -1 * pan, np.asarray([0.0, 1.0, 0.0])
        )

        sensor_offset_base = habUtils.quat_rotate_vector(
            quat_pan_to_base, sensor_offset_pan
        )
        sensor_offset_base += np.asarray([0.0, 0.5, 0.1])  # offset w.r.t base

        # translation
        quat = quat_cam_to_pan * quat_pan_to_base
        return sensor_offset_base, quat.inverse()

    def set_pan_tilt(self, pan, tilt, wait=True):
        """
		Sets both the pan and tilt joint angles to the specified values.

		:param pan: value to be set for pan joint
		:param tilt: value to be set for the tilt joint
		:param wait: wait until the pan and tilt angles are set to
		             the target angles.

		:type pan: float
		:type tilt: float
		:type wait: bool
		"""
        self.pan = pan
        self.tilt = tilt
        sensor_offset, quat_base_to_sensor = self._compute_relative_pose(pan, tilt)
        cur_state = self.agent.get_state() # Habitat frame
        sensor_position = cur_state.position + sensor_offset
        sensor_quat = cur_state.rotation * quat_base_to_sensor
        cur_state.sensor_states["rgb"].position = sensor_position
        cur_state.sensor_states["rgb"].rotation = sensor_quat

        self.agent.set_state(cur_state)

    def reset(self):
        """
		This function resets the pan and tilt joints by actuating
		them to their home configuration.
		"""
        self.set_pan_tilt(self.configs.CAMERA.RESET_PAN, self.configs.CAMERA.RESET_TILT)