00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 from __future__ import with_statement
00016 __author__ = 'Rosen Diankov'
00017 __copyright__ = 'Copyright (C) 2010 Rosen Diankov (rosen.diankov@gmail.com)'
00018 __license__ = 'Apache License, Version 2.0'
00019 import roslib; roslib.load_manifest('orrosplanning')
00020 import rospy
00021
00022 from optparse import OptionParser
00023 from openravepy import *
00024 from openravepy.misc import OpenRAVEGlobalArguments
00025 from numpy import *
00026 import numpy,time,threading
00027 from itertools import izip
00028 import tf
00029 import os
00030 import orrosplanning.srv
00031 import sensor_msgs.msg
00032 import trajectory_msgs.msg
00033 import geometry_msgs.msg
00034
00035
00036 if __name__ == "__main__":
00037 parser = OptionParser(description='openrave planning example')
00038 OpenRAVEGlobalArguments.addOptions(parser)
00039 parser.add_option('--scene',action="store",type='string',dest='scene',default='robots/pr2-beta-static.zae',
00040 help='scene to load (default=%default)')
00041 parser.add_option('--collision_map',action="store",type='string',dest='collision_map',default='/collision_map/collision_map',
00042 help='The collision map topic (maping_msgs/CollisionMap), by (default=%default)')
00043 parser.add_option('--ipython', '-i',action="store_true",dest='ipython',default=False,
00044 help='if true will drop into the ipython interpreter rather than spin')
00045 parser.add_option('--mapframe',action="store",type='string',dest='mapframe',default=None,
00046 help='The frame of the map used to position the robot. If --mapframe="" is specified, then nothing will be transformed with tf')
00047 parser.add_option('--jitter',action="store",type='float',dest='jitter',default=None,
00048 help='The jitter to use when moving robot out of collision')
00049 parser.add_option('--maxvelmult',action='store',type='float',dest='maxvelmult',default=1.0,
00050 help='The maximum velocity multiplier when timing the trajectories (default=%default)')
00051 parser.add_option('--wait-for-collisionmap',action='store',type='float',dest='wait_for_collisionmap',default=None,
00052 help='Time (seconds) to set. Will wait for the collision map time stamp to reach the same time as the service being called. If 0, will wait indefinitely.')
00053 parser.add_option('--request-for-joint_states',action='store',type='string',dest='request_for_joint_states',default='topic',
00054 help='whether to get joint states from topic or service. If ="service", will not update robot joint states until receiving service call.')
00055 parser.add_option('--use-simulation',action='store',type='string',dest='simulation',default=None,
00056 help='if use-simulation is set, we dismiss timestamp of collisionmap.')
00057 (options, args) = parser.parse_args()
00058 env = OpenRAVEGlobalArguments.parseAndCreate(options,defaultviewer=False)
00059 RaveLoadPlugin(os.path.join(roslib.packages.get_pkg_dir('orrosplanning'),'lib','liborrosplanning.so'))
00060
00061 namespace = 'openrave'
00062
00063 rospy.loginfo('initializing, please wait for ready signal...')
00064 handles = []
00065 def UpdateRobotJoints(msg):
00066 global options
00067 with envlock:
00068 with env:
00069 for name,pos in izip(msg.name,msg.position):
00070 j = robot.GetJoint(name)
00071 if j is not None:
00072 values[j.GetDOFIndex()] = pos
00073 robot.SetDOFValues(values)
00074 def UpdateRobotJointsFn(req):
00075 rospy.loginfo("Update joint states")
00076 UpdateRobotJoints(req.jointstate)
00077 return True
00078 try:
00079 rospy.init_node('armplanning_openrave',disable_signals=False)
00080 with env:
00081 env.Load(options.scene)
00082 robot = env.GetRobots()[0]
00083
00084
00085 if 1:
00086 lmodel = databases.linkstatistics.LinkStatisticsModel(robot)
00087 if not lmodel.load():
00088 lmodel.autogenerate()
00089 lmodel.setRobotWeights()
00090 lmodel.setRobotResolutions()
00091 resolutions=robot.GetDOFResolutions()
00092 weights=robot.GetDOFWeights()
00093 for j in robot.GetJoints():
00094 j.SetResolution(3.0*resolutions[j.GetDOFIndex():(j.GetDOFIndex()+j.GetDOF())])
00095 j.SetWeights(1.0*weights[j.GetDOFIndex():(j.GetDOFIndex()+j.GetDOF())])
00096
00097 ab=robot.ComputeAABB()
00098 ground=RaveCreateKinBody(env,'')
00099 ground.SetName('map')
00100 ground.InitFromBoxes(array([r_[ab.pos()-array([0,0,ab.extents()[2]+0.002]),2.0,2.0,0.001]]),True)
00101 env.AddKinBody(ground,False)
00102 if options.mapframe is None:
00103 options.mapframe = robot.GetLinks()[0].GetName()
00104 print 'setting map frame to %s'%options.mapframe
00105 collisionmap = RaveCreateSensorSystem(env,'CollisionMap expirationtime 20 bodyoffset %s topic %s'%(robot.GetName(),options.collision_map))
00106 if options.request_for_joint_states == 'topic':
00107 sub = rospy.Subscriber("/joint_states", sensor_msgs.msg.JointState, UpdateRobotJoints,queue_size=1)
00108
00109
00110
00111
00112
00113
00114
00115 if options._viewer is None:
00116 env.SetViewer('qtcoin')
00117 elif len(options._viewer) > 0:
00118 env.SetViewer(options._viewer)
00119 if len(options.mapframe) > 0:
00120 listener = tf.TransformListener()
00121 values = robot.GetDOFValues()
00122 envlock = threading.Lock()
00123
00124 postprocessing = ['shortcut_linear','<_nmaxiterations>20</_nmaxiterations><_postprocessing planner=\"parabolicsmoother\"><_nmaxiterations>40</_nmaxiterations></_postprocessing>']
00125 def MoveToHandPositionFn(req):
00126 global options
00127 rospy.loginfo("MoveToHandPosition")
00128 try:
00129 with envlock:
00130 if options.wait_for_collisionmap is not None:
00131 starttime=time.time()
00132 handgoalstamp = int64(req.hand_goal.header.stamp.to_nsec())
00133 while True:
00134 timepassed = time.time()-starttime
00135 collisionstamp = collisionmap.SendCommand("gettimestamp")
00136 if collisionstamp is not None:
00137 if int64(collisionstamp)-handgoalstamp >= 0:
00138 break
00139 if options.wait_for_collisionmap > 0 and timepassed > options.wait_for_collisionmap:
00140 if options.simulation is not None:
00141 break;
00142 raise ValueError('failed to acquire new collision map, collision timestamp is %s, service timestamp is %s'%(collisionstamp,handgoalstamp))
00143 time.sleep(0.1)
00144
00145 collisionmap.SendCommand("collisionstream 0")
00146
00147 with env:
00148 basemanip = interfaces.BaseManipulation(robot,plannername=None if len(req.planner)==0 else req.planner,maxvelmult=options.maxvelmult)
00149 rospy.loginfo("MoveToHandPosition2")
00150 if len(options.mapframe) > 0:
00151 (robot_trans,robot_rot) = listener.lookupTransform(options.mapframe, robot.GetLinks()[0].GetName(), rospy.Time(0))
00152 Trobot = matrixFromQuat([robot_rot[3],robot_rot[0],robot_rot[1],robot_rot[2]])
00153 Trobot[0:3,3] = robot_trans
00154 robot.SetTransform(Trobot)
00155 hand = listener.transformPose(options.mapframe, req.hand_goal)
00156 else:
00157 hand = req.hand_goal
00158 o = hand.pose.orientation
00159 p = hand.pose.position
00160 Thandgoal = matrixFromQuat([o.w,o.x,o.y,o.z])
00161 Thandgoal[0:3,3] = [p.x,p.y,p.z]
00162
00163 if len(req.manip_name) > 0:
00164 manip = robot.GetManipulator(req.manip_name)
00165 if manip is None:
00166 rospy.logerr('failed to find manipulator %s'%req.manip_name)
00167 return None
00168 else:
00169 manips = [manip for manip in robot.GetManipulators() if manip.GetEndEffector().GetName()==req.hand_frame_id]
00170 if len(manips) == 0:
00171 rospy.logerr('failed to find manipulator end effector %s'%req.hand_frame_id)
00172 return None
00173 manip = manips[0]
00174
00175 robot.SetActiveManipulator(manip)
00176 robot.SetActiveDOFs(manip.GetArmIndices())
00177 if len(req.hand_frame_id) > 0:
00178 handlink = robot.GetLink(req.hand_frame_id)
00179 if handlink is None:
00180 rospy.logerr('failed to find link %s'%req.hand_frame_id)
00181 return None
00182 Thandlink = handlink.GetTransform()
00183 else:
00184 Thandlink = manip.GetEndEffectorTransform()
00185 if manip.GetIkSolver() is None:
00186 rospy.loginfo('generating ik for %s'%str(manip))
00187 ikmodel = databases.inversekinematics.InverseKinematicsModel(robot,iktype=IkParameterization.Type.Transform6D)
00188 if not ikmodel.load():
00189 ikmodel.autogenerate()
00190
00191 Tgoalee = dot(Thandgoal,dot(linalg.inv(Thandlink),manip.GetTransform()))
00192 try:
00193 starttime = time.time()
00194 traj = basemanip.MoveToHandPosition(matrices=[Tgoalee],maxtries=3,seedik=4,execute=False,outputtrajobj=True,maxiter=750,jitter=options.jitter,postprocessing=postprocessing)
00195 rospy.loginfo('total planning time: %fs'%(time.time()-starttime))
00196 except:
00197 rospy.logerr('failed to solve for T=%s, error messages are:'%repr(Tgoalee))
00198 RaveSetDebugLevel(DebugLevel.Verbose)
00199 manip.FindIKSolution(Tgoalee,IkFilterOptions.CheckEnvCollisions)
00200 RaveSetDebugLevel(DebugLevel.Debug)
00201 return None
00202
00203 res = orrosplanning.srv.MoveToHandPositionResponse()
00204 spec = traj.GetConfigurationSpecification()
00205 res.traj.joint_names = [str(j.GetName()) for j in robot.GetJoints(manip.GetArmIndices())]
00206 starttime = 0.0
00207 for i in range(traj.GetNumWaypoints()):
00208 pt=trajectory_msgs.msg.JointTrajectoryPoint()
00209 data = traj.GetWaypoint(i)
00210 pt.positions = spec.ExtractJointValues(data,robot,manip.GetArmIndices(),0)
00211 starttime += spec.ExtractDeltaTime(data)
00212 pt.time_from_start = rospy.Duration(starttime)
00213 res.traj.points.append(pt)
00214 return res
00215
00216 finally:
00217 collisionmap.SendCommand("collisionstream 1")
00218
00219 def MoveManipulatorFn(req):
00220 global options
00221 rospy.loginfo("MoveManipulator")
00222 try:
00223 with envlock:
00224 if options.wait_for_collisionmap is not None:
00225 starttime=time.time()
00226 handgoalstamp = int64(req.hand_goal.header.stamp.to_nsec())
00227 while True:
00228 timepassed = time.time()-starttime
00229 collisionstamp = collisionmap.SendCommand("gettimestamp")
00230 if collisionstamp is not None:
00231 if int64(collisionstamp)-handgoalstamp >= 0:
00232 break
00233 if options.wait_for_collisionmap > 0 and timepassed > options.wait_for_collisionmap:
00234 if options.simulation is not None:
00235 break;
00236 raise ValueError('failed to acquire new collision map, collision timestamp is %s, service timestamp is %s'%(collisionstamp,handgoalstamp))
00237 time.sleep(0.1)
00238
00239 collisionmap.SendCommand("collisionstream 0")
00240
00241 with env:
00242 basemanip = interfaces.BaseManipulation(robot,plannername=None if len(req.planner)==0 else req.planner,maxvelmult=options.maxvelmult)
00243 rospy.loginfo("MoveManipulator2")
00244 manip = robot.SetActiveManipulator(req.manip_name)
00245 if manip is None:
00246 rospy.logerr('failed to find manipulator %s'%req.manip_name)
00247 return None
00248
00249 try:
00250 starttime = time.time()
00251 traj = basemanip.MoveManipulator(goal=req.manip_goal,execute=False,outputtrajobj=True,maxiter=750,jitter=options.jitter)
00252 rospy.loginfo('total planning time: %fs'%(time.time()-starttime))
00253 except:
00254 rospy.logerr('failed to solve for goal=%s, error messages are:'%repr(req.manip_goal))
00255 return None
00256
00257 res = orrosplanning.srv.MoveManipulatorResponse()
00258 spec = traj.GetConfigurationSpecification()
00259 res.traj.joint_names = [str(j.GetName()) for j in robot.GetJoints(manip.GetArmIndices())]
00260 starttime = 0.0
00261 for i in range(traj.GetNumWaypoints()):
00262 pt=trajectory_msgs.msg.JointTrajectoryPoint()
00263 data = traj.GetWaypoint(i)
00264 pt.positions = spec.ExtractJointValues(data,robot,manip.GetArmIndices(),0)
00265 starttime += spec.ExtractDeltaTime(data)
00266 pt.time_from_start = rospy.Duration(starttime)
00267 res.traj.points.append(pt)
00268 return res
00269
00270 finally:
00271 collisionmap.SendCommand("collisionstream 1")
00272
00273 if options.request_for_joint_states == 'service':
00274 js = rospy.Service('SetJointState', orrosplanning.srv.SetJointState, UpdateRobotJointsFn)
00275
00276 s1 = rospy.Service('MoveToHandPosition', orrosplanning.srv.MoveToHandPosition, MoveToHandPositionFn)
00277 s2 = rospy.Service('MoveManipulator', orrosplanning.srv.MoveManipulator, MoveManipulatorFn)
00278 RaveSetDebugLevel(DebugLevel.Debug)
00279 rospy.loginfo('openrave %s,%s service ready'%(s1.resolved_name,s2.resolved_name))
00280
00281 if options.ipython:
00282 from IPython.Shell import IPShellEmbed
00283 ipshell = IPShellEmbed(argv='',banner = 'Dropping into IPython',exit_msg = 'Leaving Interpreter, back to program.')
00284 ipshell(local_ns=locals())
00285 else:
00286 rospy.spin()
00287 finally:
00288 RaveDestroy()