00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 import roslib; roslib.load_manifest('projector_interface')
00030 from pr2_pick_and_place_demos.pick_and_place_manager import PickAndPlaceManager
00031 from geometry_msgs.msg import PointStamped, PoseStamped, PolygonStamped, Point
00032 from sensor_msgs.msg import PointCloud2
00033 from projector_interface.srv import GetCursorStats, DrawPolygon, CircleInhibit
00034 from std_msgs.msg import Empty
00035 from threading import RLock
00036 import rospy
00037 from matplotlib.nxutils import pnpoly
00038 from pr2_python.geometry_tools import euler_to_quaternion
00039 from object_manipulation_msgs.msg import ManipulationResult
00040 from copy import deepcopy
00041 import numpy as np
00042 from projector_interface._point_cloud import read_points_np
00043
00044
00045 NOTGRASPING = 0
00046 GRASPING = 1
00047
00048 x = 0.14744849503040314 - 0.03
00049 y = -0.49022838473320007 + 0.005
00050 w = 0.15
00051 h = 0.21
00052 p = 0.02
00053 RECYCLING = PolygonStamped()
00054 TRASH = PolygonStamped()
00055 RECYCLING.header.frame_id = 'table'
00056 TRASH.header.frame_id = 'table'
00057
00058 RECYCLING.polygon.points.append(Point(x , y , 0.))
00059 RECYCLING.polygon.points.append(Point(x - h, y , 0.))
00060 RECYCLING.polygon.points.append(Point(x - h, y + w, 0.))
00061 RECYCLING.polygon.points.append(Point(x , y + w, 0.))
00062
00063 TRASH.polygon.points.append( Point(x - (h+p), y, 0.))
00064 TRASH.polygon.points.append( Point(x - (2*h+p), y, 0.))
00065 TRASH.polygon.points.append( Point(x - (2*h+p), y + w, 0.))
00066 TRASH.polygon.points.append( Point(x - (h+p), y + w, 0.))
00067
00068 class Manipulator(object):
00069 state = NOTGRASPING
00070 point = None
00071 grasp_arm = -1
00072 INPROGRESS = False
00073 click_lock = RLock()
00074 def __init__(self):
00075 self.place_viz_pub = rospy.Publisher('place_pose', PoseStamped)
00076 self.manager = PickAndPlaceManager()
00077 self.cursor_proxy = rospy.ServiceProxy('get_cursor_stats', GetCursorStats)
00078
00079 rospy.loginfo("Waiting for polygon service")
00080 self.polygon_proxy = rospy.ServiceProxy('draw_polygon', DrawPolygon)
00081 self.polygon_proxy.wait_for_service()
00082 rospy.loginfo("Waiting for circle inhibit service")
00083 self.circle_inhibit_proxy = rospy.ServiceProxy('circle_inhibit', CircleInhibit)
00084 self.circle_inhibit_proxy.wait_for_service()
00085
00086 rospy.loginfo("Drawing trash/recycling")
00087 self.polygon_proxy('Recycling', True, RECYCLING)
00088 self.polygon_proxy('Garbage', True, TRASH)
00089
00090
00091 def click(self, msg):
00092 if self.click_lock.acquire(blocking=False):
00093
00094 rospy.logwarn('Calling tabletop detection')
00095 self.manager.call_tabletop_detection()
00096
00097 print 'STATE = ',self.state
00098 if self.state == NOTGRASPING:
00099 rospy.logwarn('About to grasp')
00100 self.grasp()
00101 elif self.state == GRASPING:
00102 rospy.logwarn('About to drop')
00103 self.drop()
00104 self.click_lock.release()
00105
00106
00107 def point_cb(self, msg):
00108
00109 cloud = read_points_np(msg)
00110 point = PointStamped()
00111 point.header = msg.header
00112 if cloud.shape[1] == 0: return
00113 point.point.x, point.point.y, point.point.z = cloud[0][0]
00114 self.point = point
00115
00116
00117 def transformAtLatestCommonTime(self, target_frame, point):
00118 lct = self.manager.tf_listener.getLatestCommonTime(point.header.frame_id, target_frame)
00119 point_lct = deepcopy(point)
00120 point_lct.header.stamp = lct
00121 return self.manager.tf_listener.transformPoint(target_frame, point_lct)
00122
00123
00124 def grasp(self):
00125 print self.state, self.point
00126 if (self.state == NOTGRASPING) and (self.point is not None):
00127 rospy.loginfo('===grasping')
00128 self.manager.move_arm_to_side(0)
00129 ptt = self.transformAtLatestCommonTime('base_link', self.point)
00130 status = self.manager.pick_up_object_near_point(ptt, 0)
00131 self.grasp_arm = 0
00132
00133
00134
00135
00136 if status == ManipulationResult.SUCCESS:
00137 self.state = GRASPING
00138 rospy.logerr('SUCCESSFUL GRASP')
00139 else:
00140 rospy.logerr('FAILED TO GRASP')
00141
00142 def drop(self):
00143 if self.state == GRASPING:
00144
00145 place_pose = PoseStamped()
00146 ptt = self.transformAtLatestCommonTime('table', self.point)
00147 place_pose.header = ptt.header
00148 place_pose.pose.position = ptt.point
00149 place_pose.pose.orientation = euler_to_quaternion(0,0,0)
00150 place_pose.pose.position.z = 0.03
00151
00152
00153 pw,ph = 0.1,0.1
00154
00155
00156 boxes = []
00157 for name, polygon in boxes:
00158 pts_arr = np.array([[(p.x,p.y) for p in polygon.polygon.points]])
00159 print pts_arr
00160 if pnpoly(ptt.point.x, ptt.point.y, pts_arr.squeeze()):
00161
00162
00163 poly_center = pts_arr.squeeze().mean(0)
00164 place_pose.pose.position.x = poly_center[0]
00165 place_pose.pose.position.y = poly_center[1]
00166 pw,ph = w,h
00167 rospy.loginfo('Placing in box: %s' % name)
00168
00169 rospy.loginfo('Placing at %s' % place_pose)
00170 self.place_viz_pub.publish(place_pose)
00171
00172
00173
00174 self.manager.set_place_area(place_pose, (pw,ph))
00175
00176 status = self.manager.put_down_object(self.grasp_arm, max_place_tries=25, use_place_override=1)
00177 if status == ManipulationResult.SUCCESS:
00178 self.state = NOTGRASPING
00179 self.grasp_arm = -1
00180
00181 if __name__ == '__main__':
00182 rospy.init_node('manipulator')
00183 manipulator = Manipulator()
00184 rospy.Subscriber('click', Empty, manipulator.click, queue_size=1)
00185 rospy.Subscriber('intersected_points', PointCloud2, manipulator.point_cb)
00186 rospy.loginfo('READY')
00187 rospy.spin()