detect_graspable_poses_pcabase.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 import numpy as np
00004 
00005 import rospy
00006 import sensor_msgs.point_cloud2 as pc2
00007 import tf.transformations
00008 
00009 from geometry_msgs.msg import Pose, PoseArray
00010 from jsk_topic_tools import ConnectionBasedTransport
00011 from sensor_msgs.msg import PointCloud2
00012 from sklearn.decomposition import PCA
00013 
00014 class DetectGraspablePosesPcabase(ConnectionBasedTransport):
00015 
00016     def __init__(self):
00017 
00018         rospy.logwarn("This node is experiential one.")
00019 
00020         super(DetectGraspablePosesPcabase, self).__init__()
00021 
00022         self.direction = rospy.get_param('~direction', 'x')
00023         self.hand_size = rospy.get_param('~hand_size', 0.13) # maximum hand width
00024         self.interval_m = rospy.get_param('~interval_m', '0.04') # interval of possible grasp
00025 
00026         self.pub_target_poses = self.advertise("~output/can_grasp_poses", PoseArray, queue_size=1)
00027 
00028     def subscribe(self):
00029         rospy.Subscriber('~input', PointCloud2, self.callback)
00030 
00031     def unsubscribe(self):
00032         self.sub.unregister()
00033 
00034     def callback(self, point_cloud):
00035 
00036         points = np.array(list(pc2.read_points(point_cloud, skip_nans=True)))
00037 
00038         interval_m = self.interval_m
00039 
00040         if self.direction == 'z':
00041             points_surface = points[:, [0, 1]] # choose x, y
00042         elif self.direction == 'x':
00043             points_surface = points[:, [1, 2]] # choose y, z
00044         else:
00045             rospy.logwarn("direction should be x or z")
00046 
00047         pca = PCA(n_components=2)
00048         pca.fit(points_surface)
00049         new_points = pca.transform(points_surface)
00050         new_points = new_points[np.argsort(new_points[:, 0])]
00051 
00052         min_x = new_points[0, 0]
00053         max_x = new_points[-1, 0]
00054 
00055         discrete_xy_list = []
00056 
00057         while min_x <= max_x:
00058             candidate = new_points[np.where(new_points[:, 0] < (min_x + interval_m))]
00059             new_points = new_points[np.where(new_points[:, 0] >= (min_x + interval_m))]
00060             if len(candidate) > 0:
00061                 mean_x = np.mean(candidate, axis=0)[0]
00062                 mean_y = np.mean(candidate, axis=0)[1]
00063                 range_y = np.max(candidate[:, 1]) - np.min(candidate[:, 1])
00064                 discrete_xy_list.append([mean_x, mean_y, range_y])
00065             min_x += interval_m
00066 
00067         discrete_xy_list = np.array(discrete_xy_list)
00068         discrete_xy_list = discrete_xy_list[np.where(discrete_xy_list[:, 2] < self.hand_size)]
00069         discrete_xy_list = discrete_xy_list[np.argsort(np.absolute(discrete_xy_list[:, 0]))]
00070         grasp_xy_list = pca.inverse_transform(discrete_xy_list[:, [0, 1]])
00071 
00072         search_range_m = interval_m
00073 
00074         grasp_position_list = []
00075 
00076         for grasp_xy in grasp_xy_list:
00077             if self.direction == 'z':
00078                 points_depth = points[np.where((points[:, 0] > grasp_xy[0] - search_range_m) &
00079                                                (points[:, 0] < grasp_xy[0] + search_range_m) &
00080                                                (points[:, 1] > grasp_xy[1] - search_range_m) &
00081                                                (points[:, 1] < grasp_xy[1] + search_range_m))]
00082                 points_depth = points_depth[:, 2]
00083             elif self.direction == 'x':
00084                 points_depth = points[np.where((points[:, 1] > grasp_xy[0] - search_range_m) &
00085                                                (points[:, 1] < grasp_xy[0] + search_range_m) &
00086                                                (points[:, 2] > grasp_xy[1] - search_range_m) &
00087                                                (points[:, 2] < grasp_xy[1] + search_range_m))]
00088                 points_depth = points_depth[:, 0]
00089             else:
00090                 rospy.logwarn("direction should be x or z")
00091             if len(points_depth) > 0:
00092                 grasp_position = np.append(grasp_xy, np.mean(points_depth))
00093             else:
00094                 rospy.logwarn("it happens that something wrong")
00095             grasp_position_list.append(list(grasp_position))
00096 
00097         pub_msg = PoseArray()
00098         pub_msg.header = point_cloud.header
00099 
00100         trans_matrix = tf.transformations.identity_matrix()
00101         if self.direction == 'z':
00102             trans_matrix[0, 0] = 0
00103             trans_matrix[1, 0] = 0
00104             trans_matrix[2, 0] = -1
00105             trans_matrix[0, 1] = -1 * pca.components_[0, 1]
00106             trans_matrix[1, 1] = pca.components_[0, 0]
00107             trans_matrix[0, 2] = pca.components_[0, 0]
00108             trans_matrix[1, 2] = pca.components_[0, 1]
00109             trans_matrix[2, 2] = 0
00110 
00111         elif self.direction == 'x':
00112             # this if else is set so that z value of grasp poses' y axies become positive.
00113             if pca.components_[0, 0] > 0:
00114                 trans_matrix[1, 1] = pca.components_[0, 0]
00115                 trans_matrix[2, 1] = pca.components_[0, 1]
00116                 trans_matrix[1, 2] = -1 * pca.components_[0, 1]
00117                 trans_matrix[2, 2] = pca.components_[0, 0]
00118             else:
00119                 trans_matrix[1, 1] = -1 * pca.components_[0, 0]
00120                 trans_matrix[2, 1] = -1 * pca.components_[0, 1]
00121                 trans_matrix[1, 2] = pca.components_[0, 1]
00122                 trans_matrix[2, 2] = -1 * pca.components_[0, 0]
00123         else:
00124             rospy.logwarn("direction should be x or z")
00125 
00126         quaternion = tf.transformations.quaternion_from_matrix(trans_matrix)
00127 
00128         for grasp_position in grasp_position_list:
00129             pose = Pose()
00130             if self.direction == 'z':
00131                 pose.position.x = grasp_position[0]
00132                 pose.position.y = grasp_position[1]
00133                 pose.position.z = grasp_position[2]
00134             elif self.direction == 'x':
00135                 pose.position.x = grasp_position[2]
00136                 pose.position.y = grasp_position[0]
00137                 pose.position.z = grasp_position[1]
00138             else:
00139                 rospy.logwarn("direction should x or z")
00140             pose.orientation.x = quaternion[0]
00141             pose.orientation.y = quaternion[1]
00142             pose.orientation.z = quaternion[2]
00143             pose.orientation.w = quaternion[3]
00144             pub_msg.poses.append(pose)
00145 
00146         self.pub_target_poses.publish(pub_msg)
00147 
00148 if __name__ == '__main__':
00149     rospy.init_node('detect_graspable_poses_pcabase')
00150     DetectGraspablePosesPcabase()
00151     rospy.spin()


jsk_pcl_ros
Author(s): Yohei Kakiuchi
autogenerated on Tue Jul 2 2019 19:41:42