$search
00001 # 00002 # Copyright (c) 2011, Robert Bosch LLC 00003 # All rights reserved. 00004 # 00005 # Redistribution and use in source and binary forms, with or without 00006 # modification, are permitted provided that the following conditions 00007 # are met: 00008 # 00009 # * Redistributions of source code must retain the above copyright 00010 # notice, this list of conditions and the following disclaimer. 00011 # * Redistributions in binary form must reproduce the above 00012 # copyright notice, this list of conditions and the following 00013 # disclaimer in the documentation and/or other materials provided 00014 # with the distribution. 00015 # * Neither the name of Robert Bosch LLC nor the names of its 00016 # contributors may be used to endorse or promote products derived 00017 # from this software without specific prior written permission. 00018 # 00019 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00020 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00021 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00022 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00023 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00024 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00025 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00026 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00027 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00028 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00029 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00030 # POSSIBILITY OF SUCH DAMAGE. 00031 # 00032 # 00033 # 00034 # 00035 # \author Christian Bersch 00036 # 00037 00038 #! /usr/bin/env python 00039 00040 import roslib 00041 roslib.load_manifest('pr2_interactive_segmentation') 00042 import rospy 00043 00044 import numpy 00045 00046 import sys 00047 00048 # import the necessary things for OpenCV 00049 import cv 00050 import cv_bridge 00051 import geometry_msgs.msg 00052 import sensor_msgs.msg 00053 import pr2_interactive_segmentation.srv 00054 import tf.transformations as tft 00055 import tf 00056 import simple_robot_control 00057 import camera_self_filter.srv 00058 from geometry_msgs.msg import PoseStamped 00059 from track_features_lk_class import * 00060 00061 00062 00063 class GraspExecuter(): 00064 00065 def __init__(self): 00066 00067 self.mask_service_name = "/self_mask" 00068 self.camera_topic = "kinect/rgb/image_color" 00069 self.camera_topic = "prosilica/image_rect_color" 00070 #DEBUG 00071 #self.pub = rospy.Publisher('execute_grasps/last_pos', PoseStamped) 00072 00073 00074 # print "waiting for findPokePose service" 00075 rospy.wait_for_service("findPokePose", 10.0) 00076 self._find_poke_point = rospy.ServiceProxy("findPokePose", pr2_interactive_segmentation.srv.cornerPokePoseFind()) 00077 print "waiting for %s service" % self.mask_service_name 00078 rospy.wait_for_service(self.mask_service_name, 10.0) 00079 self._getMask = rospy.ServiceProxy(self.mask_service_name, camera_self_filter.srv.mask()) 00080 self.armr = simple_robot_control.Arm('r') 00081 self.arml = simple_robot_control.Arm('l') 00082 self.arm = None 00083 self.ft = FeatureTracker() 00084 self.br = cv_bridge.CvBridge() 00085 self.forward_push_increment = 0.015#0.005 00086 self.listener = tf.TransformListener() 00087 self.arm_using = 0 00088 self.tilt_angle = [0.5, 0.5] 00089 self.gripper_frmaes = ['l_gripper_tool_frame','r_gripper_tool_frame'] 00090 seed_angles_right = (-0.93743667222127069, 0.11056515201626564, -2.064627263335348, -1.4934701151950738, -6.7198768798611708, -0.45140012228925586, 14.224670047444075) 00091 seed_angles_left = (0.54066820655626213, 0.057655477736996884, 2.1336739049387785, -1.449537220909964, 6.5549140761711637, -0.41655446503198001, -1.5841374868194875) 00092 self.seed_angles = [seed_angles_left, seed_angles_right] 00093 00094 seed_angles_right2 = (-0.93743667222127069, 0.11056515201626564, -2.064627263335348, -1.4934701151950738, -6.7198768798611708, -0.45140012228925586, 14.224670047444075) 00095 seed_angles_left2 = (0.54066820655626213, 0.057655477736996884, 2.1336739049387785, -1.449537220909964, 6.5549140761711637, -0.41655446503198001, -1.5841374868194875) 00096 self.seed_angles2 = [seed_angles_left2, seed_angles_right2] 00097 self.head = simple_robot_control.Head() 00098 self.gripr = simple_robot_control.Gripper('r') 00099 self.gripl = simple_robot_control.Gripper('l') 00100 self.above=0.02#2cm above the table 00101 00102 00103 00104 def goToPregrasp(self, side = 2, wait = True): 00105 angles_left = (1.605, 0.321, 1.297, -1.694, 0.988, -0.376, 12.053) 00106 angles_right = (-1.571, 0.374, -1.105, -1.589, -1.119, -0.276, 0.537) 00107 self.gripr.closeGripper(wait = False) 00108 self.gripl.closeGripper(wait = False) 00109 if side == 0: 00110 self.arml.goToAngle(angles_left, 5.0 , wait) 00111 if side == 1: 00112 self.armr.goToAngle(angles_right, 5.0 , wait) 00113 if side == 2: 00114 self.arml.goToAngle(angles_left, 5.0 , False) 00115 self.armr.goToAngle(angles_right, 5.0 , wait) 00116 self.head.lookAtPoint(1,0,0, 'base_link') 00117 00118 00119 00120 def _getPokePose(self, pos, orient): 00121 00122 print orient 00123 if numpy.dot(tft.quaternion_matrix(orient)[0:3,2], (0,0,1)) < 0: 00124 print "fliiping arm pose" 00125 orient = tft.quaternion_multiply(orient, (1,0,0,0)) 00126 tilt_adjust = tft.quaternion_about_axis(self.tilt_angle[self.arm_using], (0,1,0)) 00127 new_orient = tft.quaternion_multiply(orient, tilt_adjust) 00128 pos[2] += self.above #push above cm above table 00129 #DEBUG 00130 #print new_orient 00131 00132 return (pos, orient, new_orient) 00133 00134 def _findBestPose(self,poses, poses_convex): 00135 print "**********CONCAVE ONES***************",len(poses) 00136 print "**********CONVEX ONES***************",len(poses_convex) 00137 target_direction = numpy.array([1.0, 0.0, 0.0, 0.0]) 00138 def findAlign(pose): 00139 orient = pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w 00140 rot_mat = tft.quaternion_matrix(orient) 00141 #DEBUG 00142 #print "orient",orient 00143 #print "rot_mat[:,0]",rot_mat[:,0] 00144 #print "target_direction", target_direction 00145 # look for the corners that are aligned with x direction 00146 dp = numpy.dot(rot_mat[:,0], target_direction) 00147 #print "dp", dp 00148 return dp 00149 found_concave = True 00150 if len(poses) > 0: 00151 sorted_poses = sorted(poses, key = findAlign, reverse = True) 00152 #print 'sorted_poses: ', sorted_poses, sorted_poses[0] 00153 if findAlign(sorted_poses[0]) < 0: 00154 found_concave = False 00155 else: 00156 found_concave = False 00157 00158 if not found_concave: 00159 print "did not find concave corner = trying convex***********************************************************" 00160 sorted_poses = sorted(poses_convex, key = findAlign, reverse = True) 00161 if findAlign(sorted_poses[0]) < 0: 00162 print "no reachable corner whatsoever found" 00163 00164 return sorted_poses 00165 00166 00167 def _getImageAndMask(self): 00168 img_msg = rospy.wait_for_message(self.camera_topic, sensor_msgs.msg.Image, 5.0 ) 00169 mask_res = self._getMask(img_msg.header) 00170 frame = self.br.imgmsg_to_cv(img_msg) 00171 mask = self.br.imgmsg_to_cv(mask_res.mask_image) 00172 return (frame,mask) 00173 00174 00175 00176 00177 def _getInitFeatures(self): 00178 (frame, mask) = self._getImageAndMask() 00179 return self.ft.initFirstFrame(frame, mask) 00180 00181 def _getTrackedFeatures(self): 00182 (frame, mask) = self._getImageAndMask() 00183 (features, object_feature_sets) = self.ft.track(frame, mask) 00184 print "found %d objects" % (len(object_feature_sets) - 1) 00185 return features 00186 00187 def _process_features(self, last_features, new_features): 00188 #pca stuff... 00189 pass 00190 00191 def _initialPush(self): 00192 poses_res = self._find_poke_point() 00193 poses = self._findBestPose(poses_res.corner_poses, poses_res.corner_poses_convex) 00194 pose = poses[0] 00195 00196 00197 00198 print "moving arm to pose", pose 00199 00200 pos = list((pose.position.x, pose.position.y, pose.position.z)) 00201 00202 orient = pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w 00203 #DEBUG 00204 #print "pose******************************************", pos, orient 00205 00206 00207 00208 00209 #select arm 00210 # just depends on the direction 00211 rot_mat = tft.quaternion_matrix(orient) 00212 # or try this rot_mat with looking for corners 00213 if numpy.dot(rot_mat[0:3,0], (0,1,0)) > 0: 00214 print "using right arm" 00215 self.arm = self.armr 00216 self.arm_using = 1 00217 00218 else: 00219 print "using left arm" 00220 self.arm = self.arml 00221 self.arm_using = 0 00222 00223 00224 (pos,pre_orient, orient) = self._getPokePose(pos, orient) 00225 00226 #go to pre pose 00227 pre_pos = numpy.dot(tft.quaternion_matrix(pre_orient), (-0.1,0.0,0.0,0.0))[:3] + pos + (0,0,0.1) 00228 #DEBUG 00229 #print "prepose", pre_pos, pre_orient, 00230 00231 00232 00233 #backing up offset 00234 offs = numpy.dot(tft.quaternion_matrix(orient), (-0.07,0.0,0.0,0.0))[:3] 00235 offs[2] = 0.0 00236 pos = pos + offs 00237 00238 pre_pos2 = numpy.dot(tft.quaternion_matrix(orient), (-0.05,0.0,0.0,0.0))[:3] + pos 00239 00240 00241 pre_pos_0 = pre_pos + numpy.array([0.0,0.0,0.7]) 00242 00243 seed_angles = self.seed_angles[self.arm_using] 00244 #DEBUG 00245 #print 'pre_pos: ', pre_pos 00246 00247 00248 #DEBUG 00249 #pos_msg=geometry_msgs.msg.PoseStamped() 00250 #pos_msg.pose.position.x=pos[0] 00251 #pos_msg.pose.position.y=pos[1] 00252 #pos_msg.pose.position.z=pos[2] 00253 #pos_msg.pose.orientation.x=orient[0] 00254 #pos_msg.pose.orientation.y=orient[1] 00255 #pos_msg.pose.orientation.z=orient[2] 00256 #pos_msg.pose.orientation.w=orient[3] 00257 #pos_msg.header.frame_id = 'base_link' 00258 #pos_msg.header.stamp =rospy.Time(0) 00259 #pos_msg.header.seq=0; 00260 #self.pub.publish(pos_msg) 00261 00262 00263 self.arm.moveGripperToPose(pre_pos, pre_orient, 'base_link', 2.0, True, seed_angles) 00264 seed_angles = self.seed_angles2[self.arm_using] 00265 #DEBUG 00266 #print 'pre_pos2: ', pre_pos2 00267 #print 'orientation2' ,orient 00268 self.arm.moveGripperToPose(pre_pos2, orient, 'base_link',2.0, True, seed_angles) 00269 seed_angles = self.seed_angles2[self.arm_using] 00270 #print 'pos: ', pos 00271 self.arm.moveGripperToPose(pos, orient, 'base_link',2.0, True, seed_angles) 00272 00273 00274 00275 def _push(self, orient_new = None): 00276 pos,orient = self.listener.lookupTransform('base_link',self.gripper_frmaes[self.arm_using], rospy.Time()) 00277 pos_update = tft.quaternion_matrix(orient)[0:3,0] * self.forward_push_increment 00278 pos_update[2] = 0.0 00279 pos_new = pos + pos_update 00280 if orient_new == None: 00281 orient_new = orient 00282 self.arm.moveGripperToPose(pos_new, orient_new, 'base_link', 1.0) 00283 00284 00285 00286 def run(self): 00287 00288 self.goToPregrasp(2) 00289 last_features = self._getInitFeatures() 00290 self.ft.image 00291 self._initialPush() 00292 self._push() 00293 00294 term_krit = False 00295 counter = 0 00296 while not term_krit: 00297 new_features = self._getTrackedFeatures() 00298 self._process_features(last_features, new_features) 00299 self._push() 00300 last_features = new_features 00301 counter += 1 00302 term_krit = counter > 15 00303 00304 #run grasping 00305 00306 00307 00308 00309 00310 00311 00312 00313 00314 00315 00316 if __name__ == '__main__': 00317 rospy.init_node('grasp_executer') 00318 rospy.sleep(1.0) 00319 rospy.spin() 00320 00321 00322 00323 00324 00325 00326 00327 00328 00329 00330 00331 00332 00333 00334 00335