예제 #1
0
    def sample_grasps(self,
                      graspable,
                      num_grasps,
                      vis=False,
                      max_num_samples=1000):
        """
        Returns a list of candidate grasps for graspable object using uniform point pairs from the SDF

        Parameters
        ----------
        graspable : :obj:`GraspableObject3D`
            the object to grasp
        num_grasps : int
            the number of grasps to generate

        Returns
        -------
        :obj:`list` of :obj:`ParallelJawPtGrasp3D`
           list of generated grasps
        """
        # get all surface points
        surface_points, _ = graspable.sdf.surface_points(grid_basis=False)
        num_surface = surface_points.shape[0]
        i = 0
        grasps = []

        # get all grasps
        while len(grasps) < num_grasps and i < max_num_samples:
            # get candidate contacts
            indices = np.random.choice(num_surface, size=2, replace=False)
            c0 = surface_points[indices[0], :]
            c1 = surface_points[indices[1], :]

            if np.linalg.norm(c1 -
                              c0) > self.gripper.min_width and np.linalg.norm(
                                  c1 - c0) < self.gripper.max_width:
                # compute centers and axes
                grasp_center = ParallelJawPtGrasp3D.center_from_endpoints(
                    c0, c1)
                grasp_axis = ParallelJawPtGrasp3D.axis_from_endpoints(c0, c1)
                g = ParallelJawPtGrasp3D(
                    ParallelJawPtGrasp3D.configuration_from_params(
                        grasp_center, grasp_axis, self.gripper.max_width))
                # keep grasps if the fingers close
                success, contacts = g.close_fingers(graspable)
                if success:
                    grasps.append(g)
            i += 1

        return grasps
예제 #2
0
    def sample_grasps(self, graspable, openning_ratio_id, openning_ratios, vis=False):
        """Returns a list of candidate grasps for graspable object.

        Parameters
        ----------
        graspable : :obj:`GraspableObject3D`
            the object to grasp
        openning_ratio_id : int
            initial gripper openning ratio for sampling; not actual grasp openning ratio
        openning_ratios : list
            all possible opening ratios
        vis : bool
            whether or not to visualize progress, for debugging

        Returns
        -------
        :obj:`list` of :obj:`ParallelJawPtGrasp3D`
            the sampled grasps
        """
        # get surface points
        grasps = []
        surface_points, _ = graspable.sdf.surface_points(grid_basis=False)
        np.random.shuffle(surface_points)
        shuffled_surface_points = surface_points[:min(self.max_num_surface_points_, len(surface_points))]
        logging.info('Num surface: %d' %(len(surface_points)))

        for k, x_surf in enumerate(shuffled_surface_points):
            start_time = time.clock()

            # perturb grasp for num samples
            for i in range(self.num_samples):
                # perturb contact (TODO: sample in tangent plane to surface)
                x1 = self.perturb_point(x_surf, graspable.sdf.resolution)

                # compute friction cone faces
                c1 = Contact3D(graspable, x1, in_direction=None)
                _, tx1, ty1 = c1.tangents()
                cone_succeeded, cone1, n1 = c1.friction_cone(self.num_cone_faces, self.friction_coef)
                if not cone_succeeded:
                    continue
                cone_time = time.clock()

                # sample grasp axes from friction cone
                v_samples = self.sample_from_cone(n1, tx1, ty1, num_samples=1)
                sample_time = time.clock()

                for v in v_samples:
                    if vis:
                        x1_grid = graspable.sdf.transform_pt_obj_to_grid(x1)
                        cone1_grid = graspable.sdf.transform_pt_obj_to_grid(cone1, direction=True)
                        plt.clf()
                        h = plt.gcf()
                        plt.ion()
                        ax = plt.gca(projection = '3d')
                        for i in range(cone1.shape[1]):
                            ax.scatter(x1_grid[0] - cone1_grid[0], x1_grid[1] - cone1_grid[1], x1_grid[2] - cone1_grid[2], s = 50, c = u'm')

                    # # random axis flips since we don't have guarantees on surface normal directoins
                    # if random.random() > 0.5:
                    #     v = -v

                    # randomly pick grasp width & angle
                    grasp_width = openning_ratios[openning_ratio_id] * self.gripper.max_width
                    grasp_angle = np.random.rand() * np.pi * 2

                    # start searching for contacts
                    grasp, c1, c2 = ParallelJawPtGrasp3D.grasp_from_contact_and_axis_on_grid(graspable, x1, v, grasp_width, 
                                                                                             grasp_angle=grasp_angle,
                                                                                             min_grasp_width_world=self.gripper.min_width,
                                                                    
                 vis=vis)
                    
                    if grasp is None or c2 is None:
                        continue
                    # get true contacts (previous is subject to variation)
                    success, c = grasp.close_fingers(graspable)
                    if not success:
                        continue
                    c1 = c[0]
                    c2 = c[1]

                    # make sure grasp is wide enough
                    if np.linalg.norm(c1.point - c2.point) < self.min_contact_dist:
                        continue

                    # update grasp center
                    grasp.center = ParallelJawPtGrasp3D.center_from_endpoints(c1.point, c2.point)

                    # compute friction cone for new contacts
                    cone_succeeded, cone1, n1 = c1.friction_cone(self.num_cone_faces, self.friction_coef)
                    if not cone_succeeded:
                        continue
                    cone_succeeded, cone2, n2 = c2.friction_cone(self.num_cone_faces, self.friction_coef)
                    if not cone_succeeded:
                        continue

                    # check friction cone
                    if PointGraspMetrics3D.force_closure(c1, c2, self.friction_coef):
                        # try to find minimum possible openning width
                        original_max_width = grasp.max_grasp_width_
                        for index in range(openning_ratio_id):
                            grasp.max_grasp_width_ = openning_ratios[index] * self.gripper.max_width
                            success, _ = grasp.close_fingers(graspable)
                            if success:
                                break
                            else:
                                grasp.max_grasp_width_ = original_max_width
                        grasps.append(grasp)

        # randomly sample max num grasps from total list
        random.shuffle(grasps)
        return grasps