00001 import roslib; roslib.load_manifest('rcommander')
00002 import rospy
00003 import actionlib
00004 import trajectory_msgs.msg as tm
00005 import numpy as np
00006 import functools as ft
00007 import sensor_msgs.msg as sm
00008 import std_msgs.msg as stdm
00009 import pr2_controllers_msgs.msg as pm
00010 import geometry_msgs.msg as gm
00011 import time
00012
00013
00014 def unwrap2(cpos, npos):
00015 two_pi = 2*np.pi
00016 nin = npos % two_pi
00017 n_multiples_2pi = np.floor(cpos/two_pi)
00018 return nin + n_multiples_2pi*two_pi
00019
00020
00021
00022
00023
00024 class GenericListener:
00025
00026
00027
00028
00029
00030
00031
00032
00033 def __init__(self, node_name, message_type, listen_channel,
00034 frequency, message_extractor=None, queue_size=None):
00035 try:
00036 print node_name, ': inited node.'
00037 rospy.init_node(node_name, anonymous=True)
00038 except rospy.ROSException, e:
00039 pass
00040 self.last_msg_returned = None
00041 self.last_call_back = None
00042 self.delay_tolerance = 1/frequency
00043 self.reading = {'message':None, 'msg_id':-1}
00044 self.curid = 0
00045 self.message_extractor = message_extractor
00046
00047 def callback(*msg):
00048
00049 if 'header' in dir(msg):
00050 if msg.__class__ == ().__class__:
00051 msg_number = msg[0].header.seq
00052 else:
00053 msg_number = msg.header.seq
00054 else:
00055 msg_number = self.curid
00056 self.curid += 1
00057
00058
00059 if len(msg) == 1:
00060 msg = msg[0]
00061
00062 self.reading = {'message':msg, 'msg_id':msg_number}
00063
00064
00065 self.last_call_back = time.time()
00066
00067 if message_type.__class__ == [].__class__:
00068 import message_filters
00069 subscribers = [message_filters.Subscriber(channel, mtype) for channel, mtype in zip(listen_channel, message_type)]
00070 queue_size = 10
00071 ts = message_filters.TimeSynchronizer(subscribers, queue_size)
00072 ts.registerCallback(callback)
00073 else:
00074 rospy.Subscriber(listen_channel, message_type, callback,
00075 queue_size = queue_size)
00076
00077 self.node_name = node_name
00078
00079 rospy.loginfo('%s: subscribed to %s' % (node_name, listen_channel))
00080
00081 def _check_for_delivery_hiccups(self):
00082
00083 if self.last_call_back != None:
00084
00085 time_diff = time.time() - self.last_call_back
00086
00087 if time_diff > self.delay_tolerance:
00088 print self.node_name, ': have not heard back from publisher in', time_diff, 's'
00089
00090 def _wait_for_first_read(self, quiet=False):
00091 if not quiet:
00092 rospy.loginfo('%s: waiting for reading ...' % self.node_name)
00093 while self.reading['message'] == None and not rospy.is_shutdown():
00094 time.sleep(0.1)
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 def read(self, allow_duplication=False, willing_to_wait=True, warn=False, quiet=True):
00105 if allow_duplication:
00106 if willing_to_wait:
00107 raise RuntimeError('Invalid settings for read.')
00108 else:
00109
00110
00111 reading = self.reading
00112 self.last_msg_returned = reading['msg_id']
00113 if self.message_extractor is not None:
00114 return self.message_extractor(reading['message'])
00115 else:
00116 return reading['message']
00117 else:
00118 if willing_to_wait:
00119
00120 self._wait_for_first_read(quiet)
00121 while self.reading['msg_id'] == self.last_msg_returned and not rospy.is_shutdown():
00122 if warn:
00123 self._check_for_delivery_hiccups()
00124 time.sleep(1/1000.0)
00125 reading = self.reading
00126 self.last_msg_returned = reading['msg_id']
00127 if self.message_extractor is not None:
00128 return self.message_extractor(reading['message'])
00129 else:
00130 return reading['message']
00131 else:
00132
00133 if self.last_msg_returned == self.reading['msg_id']:
00134 return None
00135 else:
00136 reading = self.reading
00137 self.last_msg_returned = reading['msg_id']
00138 if self.message_extractor is not None:
00139 return self.message_extractor(reading['message'])
00140 else:
00141 return reading['message']
00142
00143
00144 class Joint:
00145
00146 def __init__(self, name, joint_provider):
00147 self.joint_provider = joint_provider
00148 self.joint_names = rospy.get_param('/%s/joints' % name)
00149 self.pub = rospy.Publisher('%s/command' % name, tm.JointTrajectory)
00150 self.names_index = None
00151 self.zeros = [0 for j in range(len(self.joint_names))]
00152
00153 def pose(self, joint_states=None):
00154 if joint_states == None:
00155 joint_states = self.joint_provider()
00156
00157 if self.names_index == None:
00158 self.names_index = {}
00159 for i, n in enumerate(joint_states.name):
00160 self.names_index[n] = i
00161 self.joint_idx = [self.names_index[n] for n in self.joint_names]
00162
00163 return (np.matrix(joint_states.position).T)[self.joint_idx, 0]
00164
00165 def _create_trajectory(self, pos_mat, times, vel_mat=None):
00166
00167 points = [tm.JointTrajectoryPoint() for i in range(pos_mat.shape[1])]
00168 for i in range(pos_mat.shape[1]):
00169 points[i].positions = pos_mat[:,i].A1.tolist()
00170 points[i].accelerations = self.zeros
00171 if vel_mat == None:
00172 points[i].velocities = self.zeros
00173 else:
00174 points[i].velocities = vel_mat[:,i].A1.tolist()
00175
00176 for i in range(pos_mat.shape[1]):
00177 points[i].time_from_start = rospy.Duration(times[i])
00178
00179
00180 jt = tm.JointTrajectory()
00181 jt.joint_names = self.joint_names
00182 jt.points = points
00183 jt.header.stamp = rospy.get_rostime()
00184 return jt
00185
00186 def set_poses(self, pos_mat, times):
00187 joint_trajectory = self._create_trajectory(pos_mat, times)
00188 self.pub.publish(joint_trajectory)
00189
00190
00191 class PR2Arm(Joint):
00192
00193
00194
00195 def __init__(self, joint_provider, tf_listener, arm, use_kinematics=True):
00196 joint_controller_name = arm + '_arm_controller'
00197 cart_controller_name = arm + '_cart'
00198 Joint.__init__(self, joint_controller_name, joint_provider)
00199 self.arm = arm
00200 self.tf_listener = tf_listener
00201 self.client = actionlib.SimpleActionClient('/%s/joint_trajectory_action' % joint_controller_name, pm.JointTrajectoryAction)
00202 self.joint_controller_name = joint_controller_name
00203
00204 self.cart_posure_pub = rospy.Publisher("/%s/command_posture" % cart_controller_name, stdm.Float64MultiArray).publish
00205 self.cart_pose_pub = rospy.Publisher("/%s/command_pose" % cart_controller_name, gm.PoseStamped).publish
00206 if arm == 'l':
00207 self.full_arm_name = 'left'
00208 else:
00209 self.full_arm_name = 'right'
00210
00211 if use_kinematics:
00212 self.kinematics = pr2k.PR2ArmKinematics(self.full_arm_name, self.tf_listener)
00213
00214
00215 self.POSTURES = {
00216 'off': np.matrix([]),
00217 'mantis': np.matrix([0, 1, 0, -1, 3.14, -1, 3.14]).T,
00218 'elbowupr': np.matrix([-0.79,0,-1.6, 9999, 9999, 9999, 9999]).T,
00219 'elbowupl': np.matrix([0.79,0,1.6 , 9999, 9999, 9999, 9999]).T,
00220 'old_elbowupr': np.matrix([-0.79,0,-1.6, -0.79,3.14, -0.79,5.49]).T,
00221 'old_elbowupl': np.matrix([0.79,0,1.6, -0.79,3.14, -0.79,5.49]).T,
00222 'elbowdownr': np.matrix([-0.028262077316910873, 1.2946342642324222, -0.25785640577652386, -1.5498884526859626]).T,
00223 'elbowdownl': np.matrix([-0.0088195719039858515, 1.2834828245284853, 0.20338442004843196, -1.5565279256852611]).T
00224 }
00225
00226 def set_posture(self, posture_mat):
00227 self.cart_posure_pub(stdm.Float64MultiArray(data=posture_mat.A1.tolist()))
00228
00229
00230
00231
00232
00233
00234
00235 def set_cart_pose(self, trans, rot, frame, msg_time):
00236 ps = gm.PoseStamped()
00237 for i, field in enumerate(['x', 'y', 'z']):
00238 exec('ps.pose.position.%s = trans[%d]' % (field, i))
00239 for i, field in enumerate(['x', 'y', 'z', 'w']):
00240 exec('ps.pose.orientation.%s = rot[%d]' % (field, i))
00241 ps.header.frame_id = frame
00242 ps.header.stamp = rospy.Time(msg_time)
00243 self.cart_pose_pub(ps)
00244
00245
00246
00247
00248 def set_poses(self, pos_mat, times, vel_mat=None, block=True):
00249 p = self.pose()
00250 for i in range(pos_mat.shape[1]):
00251 pos_mat[4,i] = unwrap2(p[4,0], pos_mat[4,i])
00252 pos_mat[6,i] = unwrap2(p[6,0], pos_mat[6,i])
00253 p = pos_mat[:,i]
00254
00255 joint_traj = Joint._create_trajectory(self, pos_mat, times, vel_mat)
00256
00257
00258 joint_traj.header.stamp = rospy.get_rostime() + rospy.Duration(1.)
00259 g = pm.JointTrajectoryGoal()
00260 g.trajectory = joint_traj
00261 self.client.send_goal(g)
00262 if block:
00263 return self.client.wait_for_result()
00264 return self.client.get_state()
00265
00266 def stop_trajectory_execution(self):
00267 self.client.cancel_all_goals()
00268
00269 def has_active_goal(self):
00270 s = self.client.get_state()
00271 if s == amsg.GoalStatus.ACTIVE or s == amsg.GoalStatus.PENDING:
00272 return True
00273 else:
00274 return False
00275
00276 def set_poses_monitored(self, pos_mat, times, vel_mat=None, block=True, time_look_ahead=.050):
00277 joint_traj = Joint._create_trajectory(self, pos_mat, times, vel_mat)
00278
00279
00280 joint_traj.header.stamp = rospy.get_rostime() + rospy.Duration(1.)
00281 g = pm.JointTrajectoryGoal()
00282 g.trajectory = joint_traj
00283 self.client.send_goal(g)
00284 if block:
00285 return self.client.wait_for_result()
00286 return self.client.get_state()
00287
00288 def set_pose(self, pos, nsecs=5., block=True):
00289 for i in range(2):
00290 cpos = self.pose()
00291 pos[4,0] = unwrap(cpos[4,0], pos[4,0])
00292 pos[6,0] = unwrap(cpos[6,0], pos[6,0])
00293 self.set_poses(np.column_stack([pos]), np.array([nsecs]), block=block)
00294
00295
00296 def pose_cartesian(self, frame='base_link'):
00297 gripper_tool_frame = self.arm + '_gripper_tool_frame'
00298 return tfu.transform(frame, gripper_tool_frame, self.tf_listener)
00299
00300 def pose_cartesian_tf(self, frame='base_link'):
00301 p, r = tfu.matrix_as_tf(self.pose_cartesian(frame))
00302 return np.matrix(p).T, np.matrix(r).T
00303
00304
00305 class PR2Torso(Joint):
00306
00307 def __init__(self, joint_provider):
00308 Joint.__init__(self, 'torso_controller', joint_provider)
00309 self.torso = actionlib.SimpleActionClient('torso_controller/position_joint_action', pm.SingleJointPositionAction)
00310 rospy.loginfo('waiting for torso_controller')
00311 self.torso.wait_for_server()
00312
00313 def set_pose(self, p, block=True):
00314 self.torso.send_goal(pm.SingleJointPositionGoal(position = p))
00315 if block:
00316 self.torso.wait_for_result()
00317 return self.torso.get_state()
00318
00319
00320 class PR2:
00321
00322 def __init__(self, tf_listener):
00323 jl = GenericListener('joint_state_listener', sm.JointState, 'joint_states', 100)
00324 joint_provider = ft.partial(jl.read, allow_duplication=False, willing_to_wait=True, warn=False, quiet=True)
00325
00326 self.left = PR2Arm(joint_provider, tf_listener, 'l', use_kinematics=False)
00327 self.right = PR2Arm(joint_provider, tf_listener, 'r', use_kinematics=False)
00328 self.torso = PR2Torso(joint_provider)