00001 """Generates a database of grasps
00002 """
00003
00004 from openravepy import *
00005 from itertools import groupby
00006 import numpy, time, analyzegrasp3d, scipy
00007 import tf, csv, os
00008 import operator, random
00009
00010
00011 import rospy, roslib
00012 from moveit_msgs.msg import *
00013 from geometry_msgs.msg import *
00014 from trajectory_msgs.msg import *
00015
00016
00017 class ORGraspGeneration:
00018 def __init__(self, viewer=False):
00019 self.env = None
00020 self.target = None
00021 self.grasp_list = None
00022
00023 def setup_environment(self, object_name, viewer=False):
00024 if self.env == None:
00025 self.env = Environment()
00026 self.env.Load(roslib.packages.get_pkg_dir('cob_grasp_generation')+'/files/env/target_scene.env.xml')
00027
00028 if viewer:
00029 if self.env.GetViewer() == None:
00030 self.env.SetViewer('qtcoin')
00031 else:
00032 print "Viewer already loaded"
00033 else:
00034 print "Not using a viewer for OpenRAVE"
00035
00036 if self.target == None:
00037 self.target = self.env.ReadKinBodyURI(roslib.packages.get_pkg_dir('cob_pick_place_action')+'/files/meshes/'+str(object_name)+'.stl')
00038 self.env.Add(self.target,True)
00039
00040 if self.target.GetName() != object_name:
00041 print "Changing the target object"
00042 self.env.Remove(self.target)
00043 self.target = self.env.ReadKinBodyURI(roslib.packages.get_pkg_dir('cob_pick_place_action')+'/files/meshes/'+str(object_name)+'.stl')
00044 self.env.Add(self.target,True)
00045
00046 print "Environment set up!"
00047
00048
00049 def generate_grasps(self, object_name, replan=False):
00050
00051 robot = self.env.GetRobots()[0]
00052 manip = robot.GetManipulator('arm')
00053 gmodel = databases.grasping.GraspingModel(robot,self.target)
00054
00055
00056 tool_trafo = manip.GetLocalToolTransform()
00057 tool_trafo[2,3] = 0.0
00058 manip.SetLocalToolTransform(tool_trafo)
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 options = self.configure_grasp_generation()
00079
00080
00081
00082
00083 now_plan = time.time()
00084
00085
00086 if gmodel.load():
00087 if replan == True:
00088 print "Replanning database"
00089 gmodel.autogenerate(options)
00090 print "Successfully loaded a database"
00091 else:
00092 print "No database available"
00093 print "Generating a database"
00094 gmodel.autogenerate(options)
00095
00096
00097
00098 end_plan = time.time()
00099 time_difference = int(end_plan - now_plan)
00100 print "GraspGeneration took: ", time_difference
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 validgrasps, validindicees = gmodel.computeValidGrasps(checkcollision=True, checkik=False)
00112
00113
00114 print "TotalNumValidGrasps: ",len(validgrasps)
00115
00116
00117 if len(validgrasps) == 0:
00118 print('No valid grasps generated')
00119 return []
00120 databases.grasping.RaveDestroy()
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 grasps_to_file = []
00149 meta_info = []
00150 meta_info.append(object_name)
00151 meta_info.append(time)
00152 grasps_to_file.append(meta_info)
00153
00154
00155 for graspnmb in range(0,len(validgrasps)):
00156
00157
00158 auto_fill_rest = False
00159
00160 grasp_to_file = []
00161 grasp_to_file.append(graspnmb)
00162 grasp_num = int(graspnmb)
00163
00164
00165 try:
00166 print "Grasp: ",graspnmb
00167 contacts,finalconfig,mindist,volume = gmodel.runGrasp(grasp=validgrasps[grasp_num], forceclosure=True)
00168 except:
00169 print "something went wrong"
00170 mindist = 0.0
00171 volume = 0.0
00172
00173
00174 direction = gmodel.getGlobalApproachDir(validgrasps[graspnmb])
00175
00176 transf = []
00177
00178 with gmodel.GripperVisibility(manip):
00179 with self.env:
00180 gmodel.setPreshape(validgrasps[graspnmb])
00181 Tgrasp = gmodel.getGlobalGraspTransform(validgrasps[graspnmb],collisionfree=True)
00182 Tdelta = numpy.dot(Tgrasp,numpy.linalg.inv(manip.GetEndEffectorTransform()))
00183 DOFValues = robot.GetActiveDOFValues()
00184 DOFValues[manip.GetGripperIndices()] = finalconfig[0][manip.GetGripperIndices()]
00185 robot.SetDOFValues(DOFValues)
00186 robot.SetTransform(numpy.dot(Tdelta,robot.GetTransform()))
00187 self.env.UpdatePublishedBodies()
00188 with self.target:
00189 self.target.SetTransform(numpy.eye(4))
00190 with gmodel.GripperVisibility(manip):
00191 with self.env:
00192 gmodel.setPreshape(validgrasps[graspnmb])
00193 Tgrasp = gmodel.getGlobalGraspTransform(validgrasps[graspnmb],collisionfree=True)
00194 Tdelta = numpy.dot(Tgrasp,numpy.linalg.inv(manip.GetEndEffectorTransform()))
00195 for link in manip.GetChildLinks():
00196 link.SetTransform(numpy.dot(Tdelta,link.GetTransform()))
00197 self.env.UpdatePublishedBodies()
00198
00199 transf = manip.GetEndEffectorTransform()
00200
00201 grasp_to_file.append(finalconfig[0][manip.GetGripperIndices()])
00202 grasp_to_file.append(transf)
00203
00204 grasp_to_file.append(mindist)
00205 grasp_to_file.append(volume)
00206
00207 forceclosure = validgrasps[graspnmb][gmodel.graspindices['forceclosure']]
00208 grasp_to_file.append(forceclosure)
00209 grasp_to_file.append(validindicees[graspnmb])
00210 grasp_to_file.append(direction)
00211
00212
00213
00214 grasps_to_file.append(grasp_to_file)
00215
00216 gmodel.getGlobalApproachDir(validgrasps[graspnmb])
00217
00218
00219 analyzegrasp3d.or_to_csv(grasps_to_file)
00220
00221 print('Finished.')
00222 databases.grasping.RaveDestroy()
00223 return len(validgrasps)
00224
00225
00226
00227 def configure_grasp_generation(self):
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 preshape_array = []
00248
00249
00250 preshape = '0.0 -0.9854 0.9472 -0.9854 0.9472 -0.9854 0.9472'
00251 preshape_array.append(preshape)
00252 preshape = '0.0 -0.9854 0.47 -0.9854 0.47 -0.9854 0.47'
00253 preshape_array.append(preshape)
00254
00255
00256 options.preshapes = numpy.array(preshape_array)
00257
00258
00259
00260
00261
00262
00263
00264
00265 options.boxdelta = 0.05
00266
00267
00268
00269
00270
00271 standoff_array = [0.025, 0.075]
00272 options.standoffs = numpy.array(standoff_array)
00273
00274
00275
00276
00277 options.friction = 1.0
00278
00279
00280
00281
00282
00283
00284
00285
00286 options.normalanglerange = 0.0
00287
00288
00289
00290 options.directiondelta = 1
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 return options
00301
00302
00303
00304 def check_database(self, object_name):
00305
00306 path_in = roslib.packages.get_pkg_dir('cob_grasp_generation')+'/files/database/'+object_name+'/'+object_name+'.csv'
00307
00308
00309 if os.path.exists(path_in):
00310 return True
00311 else:
00312 return False
00313
00314
00315
00316 def get_grasp_list(self, object_name, sort_by_quality=False):
00317
00318 path_in = roslib.packages.get_pkg_dir('cob_grasp_generation')+'/files/database/'+object_name+'/'+object_name+'.csv'
00319
00320
00321 try:
00322 with open(path_in) as f: pass
00323 except IOError as e:
00324 rospy.logerr("The path or file does not exist: "+path_in)
00325
00326
00327 reader = csv.DictReader( open(path_in, "rb"), delimiter=',')
00328
00329 if sort_by_quality:
00330
00331 self.grasp_list = sorted(reader, key=lambda d: float(d['eps_l1']), reverse=True)
00332 else:
00333 self.grasp_list = sorted(reader, key=lambda d: float(d['id']), reverse=False)
00334
00335
00336
00337 def get_grasps(self, object_name, grasp_id=0, num_grasps=0, threshold=0):
00338
00339 self.get_grasp_list(object_name)
00340
00341
00342 if grasp_id > 0:
00343 if grasp_id < len(self.grasp_list):
00344
00345 return [self._fill_grasp_msg(self.grasp_list[grasp_id])]
00346 else:
00347 print "Grasp not available"
00348 return []
00349
00350
00351 sorted_list = sorted(self.grasp_list, key=lambda d: float(d['eps_l1']), reverse=True)
00352
00353
00354 if num_grasps > 0:
00355 max_grasps=min(len(sorted_list),num_grasps)
00356 else:
00357 max_grasps=len(sorted_list)
00358
00359
00360 selected_grasp_list = []
00361 for i in range(0,max_grasps):
00362 if threshold > 0 and float(sorted_list[i]['eps_l1']) >= threshold:
00363 selected_grasp_list.append(self._fill_grasp_msg(sorted_list[i]))
00364 elif threshold == 0:
00365 selected_grasp_list.append(self._fill_grasp_msg(sorted_list[i]))
00366 else:
00367 pass
00368
00369
00370 return selected_grasp_list
00371
00372
00373
00374 def _fill_grasp_msg(self, grasp):
00375
00376
00377 joint_config = JointTrajectory()
00378 joint_config.header.stamp = rospy.Time.now()
00379
00380 joint_config.joint_names = ['sdh_knuckle_joint', 'sdh_finger_12_joint', 'sdh_finger_13_joint', 'sdh_finger_22_joint', 'sdh_finger_23_joint', 'sdh_thumb_2_joint', 'sdh_thumb_3_joint']
00381 print "Optimize grasp_configuration"
00382 for joint_name in joint_config.joint_names:
00383 point = JointTrajectoryPoint()
00384 point.positions.append(float(grasp[joint_name]))
00385 point.velocities.append(0.0)
00386 point.accelerations.append(0.0)
00387 point.time_from_start = rospy.Duration(3.0)
00388 joint_config.points.append(point)
00389
00390
00391
00392
00393
00394
00395
00396 pre_joint_config = JointTrajectory()
00397 pre_joint_config.header.stamp = rospy.Time.now()
00398 pre_joint_config.joint_names = ['sdh_knuckle_joint', 'sdh_finger_12_joint', 'sdh_finger_13_joint', 'sdh_finger_22_joint', 'sdh_finger_23_joint', 'sdh_thumb_2_joint', 'sdh_thumb_3_joint']
00399 cyl_open = [0.0, -0.9854, 0.9472, -0.9854, 0.9472, -0.9854, 0.9472]
00400
00401 for i in range(len(pre_joint_config.joint_names)):
00402 point = JointTrajectoryPoint()
00403 point.positions.append(cyl_open[i])
00404 point.velocities.append(0.0)
00405 point.accelerations.append(0.0)
00406 point.time_from_start = rospy.Duration(3.0)
00407 pre_joint_config.points.append(point)
00408 print pre_joint_config
00409
00410
00411 grasp_pose = PoseStamped()
00412 grasp_pose.header.stamp = rospy.Time.now()
00413
00414 grasp_pose.pose.position.x = float(grasp['pos-x'])*0.001
00415 grasp_pose.pose.position.y = float(grasp['pos-y'])*0.001
00416 grasp_pose.pose.position.z = float(grasp['pos-z'])*0.001
00417 grasp_pose.pose.orientation.x = float(grasp['qx'])
00418 grasp_pose.pose.orientation.y = float(grasp['qy'])
00419 grasp_pose.pose.orientation.z = float(grasp['qz'])
00420 grasp_pose.pose.orientation.w = float(grasp['qw'])
00421
00422
00423 grasp_out = Grasp()
00424 grasp_out.id = grasp['id']
00425 grasp_out.pre_grasp_posture = pre_joint_config
00426 grasp_out.grasp_posture = joint_config
00427 grasp_out.grasp_pose = grasp_pose
00428 grasp_out.grasp_quality = float(grasp['eps_l1'])
00429 grasp_out.max_contact_force = 0
00430
00431 return grasp_out
00432
00433
00434 def show_grasp(self, object_name, grasp_id, sort_by_quality=False):
00435 self.setup_environment(object_name, viewer=True)
00436
00437 self.get_grasp_list(object_name, sort_by_quality)
00438
00439
00440
00441 robot = self.env.GetRobots()[0]
00442 manip = robot.GetManipulator('arm')
00443 gmodel = databases.grasping.GraspingModel(robot,self.target)
00444
00445
00446 tool_trafo = manip.GetLocalToolTransform()
00447 tool_trafo[2,3] = 0.0
00448 manip.SetLocalToolTransform(tool_trafo)
00449
00450
00451
00452 grasp = self.grasp_list[int(grasp_id)]
00453 print 'Grasp ID: '+str(grasp['id'])
00454 print 'Grasp Quality epsilon: '+str(grasp['eps_l1'])
00455 print 'Grasp Quality volume: '+str(grasp['vol_l1'])
00456
00457
00458 with gmodel.GripperVisibility(manip):
00459 dof_array = [0]*27
00460 dof_array[7:13] =[float(grasp['sdh_finger_22_joint']),float(grasp['sdh_finger_23_joint']),float(grasp['sdh_knuckle_joint']),float(grasp['sdh_finger_12_joint']),float(grasp['sdh_finger_13_joint']),float(grasp['sdh_thumb_2_joint']),float(grasp['sdh_thumb_3_joint'])]
00461 robot.SetDOFValues(numpy.array(dof_array))
00462
00463
00464 mm_in_m = 0.001
00465 pos = [float(grasp['pos-x'])*mm_in_m, float(grasp['pos-y'])*mm_in_m, float(grasp['pos-z'])*mm_in_m]
00466 quat = [float(grasp['qw']), float(grasp['qx']), float(grasp['qy']), float(grasp['qz'])]
00467 Tgrasp = matrixFromPose(quat+pos)
00468
00469
00470 Tdelta = numpy.dot(Tgrasp,numpy.linalg.inv(manip.GetEndEffectorTransform()))
00471 for link in manip.GetChildLinks():
00472 link.SetTransform(numpy.dot(Tdelta,link.GetTransform()))
00473
00474
00475 time.sleep(1)
00476 self.env.UpdatePublishedBodies()
00477
00478