00001 import roslib; roslib.load_manifest('hrl_pr2_lib')
00002 import rospy
00003
00004 import actionlib
00005 import actionlib_msgs.msg as amsg
00006 import move_base_msgs.msg as mm
00007 import sensor_msgs.msg as sm
00008 import pr2_controllers_msgs.msg as pm
00009 import trajectory_msgs.msg as tm
00010 import pr2_mechanism_msgs.srv as pmm
00011 import std_msgs.msg as stdm
00012 import geometry_msgs.msg as gm
00013 import dynamic_reconfigure.client as dc
00014
00015 import tf
00016 import tf.transformations as tr
00017 import hrl_lib.tf_utils as tfu
00018 import hrl_lib.rutils as ru
00019 import hrl_lib.util as ut
00020 import functools as ft
00021 import numpy as np
00022 import math
00023 import time
00024 import hrl_pr2_lib.msg as hm
00025
00026
00027 import pr2_kinematics as pr2k
00028 import os
00029 import os.path as pt
00030 import pdb
00031
00032
00033
00034 def unwrap2(cpos, npos):
00035 two_pi = 2*np.pi
00036 nin = npos % two_pi
00037 n_multiples_2pi = np.floor(cpos/two_pi)
00038 return nin + n_multiples_2pi*two_pi
00039
00040
00041 def unwrap(cpos, npos):
00042 two_pi = 2*np.pi
00043 if cpos < npos:
00044 while cpos < npos:
00045 npos = npos - two_pi
00046 npos = npos + two_pi
00047 elif cpos > npos:
00048 while cpos > npos:
00049 npos = npos + two_pi
00050 npos = npos - two_pi
00051 return npos
00052
00053
00054 def diff_arm_pose(pose1, pose2):
00055 pcpy = pose2.copy()
00056 pcpy[4,0] = unwrap2(pose1[4,0], pose2[4,0])
00057 pcpy[6,0] = unwrap2(pose1[6,0], pose2[6,0])
00058 diff = pose1 - pose2
00059 for i in range(pose1.shape[0]):
00060 diff[i,0] = ut.standard_rad(diff[i,0])
00061 return diff
00062
00063
00064 class KinematicsError(Exception):
00065 def __init__(self, value):
00066 self.parameter = value
00067
00068 def __str__(self):
00069 return repr(self.parameter)
00070
00071 class Joint:
00072
00073 def __init__(self, name, joint_provider):
00074 self.joint_provider = joint_provider
00075 self.joint_names = rospy.get_param('/%s/joints' % name)
00076 self.pub = rospy.Publisher('%s/command' % name, tm.JointTrajectory)
00077 self.names_index = None
00078 self.zeros = [0 for j in range(len(self.joint_names))]
00079
00080 def pose(self, joint_states=None):
00081 if joint_states == None:
00082 joint_states = self.joint_provider()
00083
00084 if self.names_index == None:
00085 self.names_index = {}
00086 for i, n in enumerate(joint_states.name):
00087 self.names_index[n] = i
00088 self.joint_idx = [self.names_index[n] for n in self.joint_names]
00089
00090 return (np.matrix(joint_states.position).T)[self.joint_idx, 0]
00091
00092 def _create_trajectory(self, pos_mat, times, vel_mat=None):
00093
00094 points = [tm.JointTrajectoryPoint() for i in range(pos_mat.shape[1])]
00095 for i in range(pos_mat.shape[1]):
00096 points[i].positions = pos_mat[:,i].A1.tolist()
00097 points[i].accelerations = self.zeros
00098 if vel_mat == None:
00099 points[i].velocities = self.zeros
00100 else:
00101 points[i].velocities = vel_mat[:,i].A1.tolist()
00102
00103 for i in range(pos_mat.shape[1]):
00104 points[i].time_from_start = rospy.Duration(times[i])
00105
00106
00107 jt = tm.JointTrajectory()
00108 jt.joint_names = self.joint_names
00109 jt.points = points
00110 jt.header.stamp = rospy.get_rostime()
00111 return jt
00112
00113 def set_poses(self, pos_mat, times):
00114 joint_trajectory = self._create_trajectory(pos_mat, times)
00115 self.pub.publish(joint_trajectory)
00116
00117
00118 class PR2Arm(Joint):
00119
00120 def __init__(self, joint_provider, tf_listener, arm, use_kinematics=True):
00121 joint_controller_name = arm + '_arm_controller'
00122 cart_controller_name = arm + '_arm_cartesian_pose_controller'
00123 Joint.__init__(self, joint_controller_name, joint_provider)
00124 self.arm = arm
00125 self.tf_listener = tf_listener
00126 self.client = actionlib.SimpleActionClient('/%s/joint_trajectory_action' % joint_controller_name, pm.JointTrajectoryAction)
00127 rospy.loginfo('pr2arm: waiting for server %s' % joint_controller_name)
00128 self.client.wait_for_server()
00129 self.joint_controller_name = joint_controller_name
00130
00131 self.cart_posture_pub = rospy.Publisher("/%s/command_posture" % cart_controller_name, stdm.Float64MultiArray).publish
00132 self.cart_pose_pub = rospy.Publisher("/%s/command" % cart_controller_name, gm.PoseStamped).publish
00133 if arm == 'l':
00134 self.full_arm_name = 'left'
00135 else:
00136 self.full_arm_name = 'right'
00137 if use_kinematics:
00138 self.kinematics = pr2k.PR2ArmKinematics(self.full_arm_name,
00139 self.tf_listener)
00140
00141
00142 self.POSTURES = {
00143 'off': np.matrix([]),
00144 'mantis': np.matrix([0, 1, 0, -1, 3.14, -1, 3.14]).T,
00145 'elbowupr': np.matrix([-0.79,0,-1.6, 9999, 9999, 9999, 9999]).T,
00146 'elbowupl': np.matrix([0.79,0,1.6 , 9999, 9999, 9999, 9999]).T,
00147 'old_elbowupr': np.matrix([-0.79,0,-1.6, -0.79,3.14, -0.79,5.49]).T,
00148 'old_elbowupl': np.matrix([0.79,0,1.6, -0.79,3.14, -0.79,5.49]).T,
00149 'elbowdownr': np.matrix([-0.028262077316910873, 1.2946342642324222, -0.25785640577652386, -1.5498884526859626]).T,
00150 'elbowdownl': np.matrix([-0.0088195719039858515, 1.2834828245284853, 0.20338442004843196, -1.5565279256852611]).T
00151 }
00152
00153 def set_posture(self, posture_mat):
00154 self.cart_posture_pub(stdm.Float64MultiArray(data=posture_mat.A1.tolist()))
00155
00156
00157
00158
00159
00160
00161
00162 def set_cart_pose(self, trans, rot, frame, msg_time):
00163 ps = gm.PoseStamped()
00164 for i, field in enumerate(['x', 'y', 'z']):
00165 exec('ps.pose.position.%s = trans[%d]' % (field, i))
00166 for i, field in enumerate(['x', 'y', 'z', 'w']):
00167 exec('ps.pose.orientation.%s = rot[%d]' % (field, i))
00168 ps.header.frame_id = frame
00169 ps.header.stamp = rospy.Time(msg_time)
00170 self.cart_pose_pub(ps)
00171
00172
00173
00174
00175 def set_poses(self, pos_mat, times, vel_mat=None, block=True):
00176 p = self.pose()
00177 for i in range(pos_mat.shape[1]):
00178 pos_mat[4,i] = unwrap2(p[4,0], pos_mat[4,i])
00179 pos_mat[6,i] = unwrap2(p[6,0], pos_mat[6,i])
00180 p = pos_mat[:,i]
00181
00182 joint_traj = Joint._create_trajectory(self, pos_mat, times, vel_mat)
00183
00184
00185 joint_traj.header.stamp = rospy.get_rostime() + rospy.Duration(1.)
00186 g = pm.JointTrajectoryGoal()
00187 g.trajectory = joint_traj
00188 self.client.send_goal(g)
00189 if block:
00190 return self.client.wait_for_result()
00191 return self.client.get_state()
00192
00193 def stop_trajectory_execution(self):
00194 self.client.cancel_all_goals()
00195
00196 def has_active_goal(self):
00197 s = self.client.get_state()
00198 if s == amsg.GoalStatus.ACTIVE or s == amsg.GoalStatus.PENDING:
00199 return True
00200 else:
00201 return False
00202
00203 def set_poses_monitored(self, pos_mat, times, vel_mat=None, block=True, time_look_ahead=.050):
00204 joint_traj = Joint._create_trajectory(self, pos_mat, times, vel_mat)
00205
00206
00207 joint_traj.header.stamp = rospy.get_rostime() + rospy.Duration(1.)
00208 g = pm.JointTrajectoryGoal()
00209 g.trajectory = joint_traj
00210 self.client.send_goal(g)
00211 if block:
00212 return self.client.wait_for_result()
00213 return self.client.get_state()
00214
00215 def set_pose(self, pos, nsecs=5., block=True):
00216 for i in range(2):
00217 cpos = self.pose()
00218 pos[4,0] = unwrap(cpos[4,0], pos[4,0])
00219 pos[6,0] = unwrap(cpos[6,0], pos[6,0])
00220 self.set_poses(np.column_stack([pos]), np.array([nsecs]), block=block)
00221
00222
00223 def pose_cartesian(self, frame='base_link'):
00224 gripper_tool_frame = self.arm + '_gripper_tool_frame'
00225 return tfu.transform(frame, gripper_tool_frame, self.tf_listener)
00226
00227 def pose_cartesian_tf(self, frame='base_link'):
00228 p, r = tfu.matrix_as_tf(self.pose_cartesian(frame))
00229 return np.matrix(p).T, np.matrix(r).T
00230
00231
00232 class PR2Head(Joint):
00233
00234 def __init__(self, name, joint_provider):
00235 Joint.__init__(self, name, joint_provider)
00236 self.head_client = actionlib.SimpleActionClient('head_traj_controller/point_head_action',
00237 pm.PointHeadAction)
00238
00239 def look_at(self, pt3d, frame='base_link', pointing_frame="wide_stereo_link",
00240 pointing_axis=np.matrix([1, 0, 0.]).T, wait=True):
00241 g = pm.PointHeadGoal()
00242 g.target.header.frame_id = frame
00243 g.target.point = gm.Point(*pt3d.T.A1.tolist())
00244
00245
00246 g.pointing_frame = pointing_frame
00247 g.pointing_axis.x = pointing_axis[0,0]
00248 g.pointing_axis.y = pointing_axis[1,0]
00249 g.pointing_axis.z = pointing_axis[2,0]
00250 g.min_duration = rospy.Duration(1.0)
00251 g.max_velocity = 10.
00252
00253 self.head_client.send_goal(g)
00254 if wait:
00255 self.head_client.wait_for_result(rospy.Duration(1.))
00256 if self.head_client.get_state() == amsg.GoalStatus.SUCCEEDED:
00257 return True
00258 else:
00259 return False
00260
00261 def set_pose(self, pos, nsecs=5.):
00262 for i in range(2):
00263 cpos = self.pose()
00264 min_time = .1
00265 self.set_poses(np.column_stack([cpos, pos]), np.array([min_time, min_time+nsecs]))
00266
00267
00268
00269
00270 class PR2Base:
00271 def __init__(self, tflistener):
00272 self.tflistener = tflistener
00273 self.client = actionlib.SimpleActionClient('move_base', mm.MoveBaseAction)
00274 rospy.loginfo('pr2base: waiting for move_base')
00275 self.client.wait_for_server()
00276 rospy.loginfo('pr2base: waiting transforms')
00277 try:
00278 self.tflistener.waitForTransform('map', 'base_footprint', rospy.Time(), rospy.Duration(20))
00279 except Exception, e:
00280 rospy.loginfo('pr2base: WARNING! Transform from map to base_footprint not found! Did you launch the nav stack?')
00281
00282
00283 self.go_angle_client = actionlib.SimpleActionClient('go_angle', hm.GoAngleAction)
00284 self.go_xy_client = actionlib.SimpleActionClient('go_xy', hm.GoXYAction)
00285
00286
00287
00288 def turn_to(self, angle, block=True):
00289 goal = hm.GoAngleGoal()
00290 goal.angle = angle
00291 self.go_angle_client.send_goal(goal)
00292 print 'SENT TURN GOAL'
00293 if block:
00294 rospy.loginfo('turn_to: waiting for turn..')
00295 self.go_angle_client.wait_for_result()
00296 rospy.loginfo('turn_to: done.')
00297
00298
00299
00300
00301 def turn_by(self, delta_ang, block=True, overturn=False):
00302
00303 if overturn and (abs(delta_ang) < math.radians(10.)):
00304
00305 turn1 = np.sign(delta_ang) * math.radians(15.) + delta_ang
00306 turn2 = -np.sign(delta_ang) * math.radians(15.)
00307 rospy.loginfo('Requested really small turn angle. Using overturn trick.')
00308
00309 self._turn_by(turn1, block=True)
00310 time.sleep(3)
00311 self._turn_by(turn2, block)
00312 else:
00313 self._turn_by(delta_ang, block)
00314
00315
00316 def _turn_by(self, delta_ang, block=True):
00317 current_ang_odom = tr.euler_from_matrix(tfu.transform('base_footprint',\
00318 'odom_combined', self.tflistener)[0:3, 0:3], 'sxyz')[2]
00319 self.turn_to(current_ang_odom + delta_ang, block)
00320
00321
00322
00323
00324 def move_to(self, xy_loc_bf, block=True):
00325 goal = hm.GoXYGoal()
00326 goal.x = xy_loc_bf[0,0]
00327 goal.y = xy_loc_bf[1,0]
00328 self.go_xy_client.send_goal(goal)
00329 if block:
00330 self.go_xy_client.wait_for_result()
00331
00332 def set_pose(self, t, r, frame, block=True):
00333 g = mm.MoveBaseGoal()
00334 p = g.target_pose
00335
00336 p.header.frame_id = frame
00337 p.header.stamp = rospy.get_rostime()
00338 p.pose.position.x = t[0]
00339 p.pose.position.y = t[1]
00340 p.pose.position.z = 0
00341
00342 p.pose.orientation.x = r[0]
00343 p.pose.orientation.y = r[1]
00344 p.pose.orientation.z = r[2]
00345 p.pose.orientation.w = r[3]
00346
00347 self.client.send_goal(g)
00348 if block:
00349 self.client.wait_for_result()
00350 return self.client.get_state()
00351
00352 def get_pose(self):
00353 p_base = tfu.transform('map', 'base_footprint', self.tflistener) \
00354 * tfu.tf_as_matrix(([0., 0., 0., 1.], tr.quaternion_from_euler(0,0,0)))
00355 return tfu.matrix_as_tf(p_base)
00356
00357
00358 class PR2Torso(Joint):
00359
00360 def __init__(self, joint_provider):
00361 Joint.__init__(self, 'torso_controller', joint_provider)
00362 self.torso = actionlib.SimpleActionClient('torso_controller/position_joint_action', pm.SingleJointPositionAction)
00363 rospy.loginfo('waiting for torso_controller')
00364 self.torso.wait_for_server()
00365
00366 def set_pose(self, p, block=True):
00367 self.torso.send_goal(pm.SingleJointPositionGoal(position = p))
00368 if block:
00369 self.torso.wait_for_result()
00370 return self.torso.get_state()
00371
00372
00373 class PR2Gripper:
00374
00375 def __init__(self, gripper, joint_provider):
00376 self.gripper = gripper
00377 self.joint_provider = joint_provider
00378
00379 if gripper == 'l':
00380 self.client = actionlib.SimpleActionClient(
00381 'l_gripper_controller/gripper_action', pm.Pr2GripperCommandAction)
00382 self.full_gripper_name = 'left_gripper'
00383 self.joint_names = [rospy.get_param('/l_gripper_controller/joint')]
00384 else:
00385 self.client = actionlib.SimpleActionClient(
00386 'r_gripper_controller/gripper_action', pm.Pr2GripperCommandAction)
00387 self.full_gripper_name = 'right_gripper'
00388 self.joint_names = [rospy.get_param('/r_gripper_controller/joint')]
00389 self.client.wait_for_server()
00390 self.names_index = None
00391
00392 def pose(self, joint_states=None):
00393 if joint_states == None:
00394 joint_states = self.joint_provider()
00395
00396 if self.names_index == None:
00397 self.names_index = {}
00398 for i, n in enumerate(joint_states.name):
00399 self.names_index[n] = i
00400 self.joint_idx = [self.names_index[n] for n in self.joint_names]
00401
00402 return (np.matrix(joint_states.position).T)[self.joint_idx, 0]
00403
00404 def close(self, block, position=0.0, effort=-1):
00405 self.client.send_goal(pm.Pr2GripperCommandGoal(
00406 pm.Pr2GripperCommand(position = position, max_effort = effort)))
00407 if block:
00408 self.client.wait_for_result()
00409 return self.client.get_state()
00410
00411 def open(self, block, position=0.1, effort = -1):
00412 self.client.send_goal(pm.Pr2GripperCommandGoal(
00413 pm.Pr2GripperCommand(position = position, max_effort = effort)))
00414 if block:
00415 self.client.wait_for_result()
00416 return self.client.get_state()
00417
00418 class StructuredLightProjector:
00419 def __init__(self):
00420 self.client = dc.Client("camera_synchronizer_node")
00421
00422 def set(self, on):
00423 config = {"projector_mode":2}
00424 if on:
00425 config["narrow_stereo_trig_mode"] = 3
00426 else:
00427 config["narrow_stereo_trig_mode"] = 2
00428 self.client.update_configuration(config)
00429
00430 def set_prosilica_inhibit(self, on):
00431 self.node_config['prosilica_projector_inhibit'] = on
00432 self.client.update_configuration(self.node_config)
00433
00434
00435 class ControllerManager:
00436
00437 def __init__(self):
00438
00439 self.load = rospy.ServiceProxy('pr2_controller_manager/load_controller', pmm.LoadController)
00440
00441 self.unload = rospy.ServiceProxy('pr2_controller_manager/unload_controller', pmm.UnloadController)
00442
00443 self._switch_controller = rospy.ServiceProxy('pr2_controller_manager/switch_controller', pmm.SwitchController)
00444
00445 def switch(self, start_con, stop_con):
00446 for n in start_con:
00447 self.load(n)
00448 resp = self._switch_controller(start_con, stop_con, pmm.SwitchControllerRequest.STRICT)
00449 for n in stop_con:
00450 self.unload(n)
00451 return resp.ok
00452
00453
00454 class SoundPlay:
00455
00456 def __init__(self):
00457 self.ros_home = pt.join(os.getenv("HOME"), '.ros')
00458
00459 def say(self, phrase):
00460 wav_file_name = pt.join(self.ros_home, 'soundplay_temp.wav')
00461 os.system("text2wave %s -o %s" % (phrase, wav_file_name))
00462 os.system("aplay %s" % (wav_file_name))
00463
00464 def play(self, filename):
00465 os.system("aplay %s" % filename)
00466
00467
00468 class PR2:
00469
00470 def __init__(self, tf_listener=None, arms=True, base=False, grippers=True,
00471 use_kinematics=True, use_projector=True):
00472 try:
00473 rospy.init_node('pr2', anonymous=True)
00474 except rospy.exceptions.ROSException, e:
00475 pass
00476
00477 if tf_listener == None:
00478 self.tf_listener = tf.TransformListener()
00479 else:
00480 self.tf_listener = tf_listener
00481 jl = ru.GenericListener('joint_state_listener', sm.JointState, 'joint_states', 100)
00482 self.joint_provider = ft.partial(jl.read, allow_duplication=False, willing_to_wait=True, warn=False, quiet=True)
00483
00484 if arms:
00485 self.left = PR2Arm(self.joint_provider, self.tf_listener, 'l',
00486 use_kinematics)
00487 self.right = PR2Arm(self.joint_provider, self.tf_listener, 'r',
00488 use_kinematics)
00489
00490 if grippers:
00491 self.left_gripper = PR2Gripper('l', self.joint_provider)
00492 self.right_gripper = PR2Gripper('r', self.joint_provider)
00493
00494 self.head = PR2Head('head_traj_controller', self.joint_provider)
00495
00496 if base:
00497 self.base = PR2Base(self.tf_listener)
00498 self.torso = PR2Torso(self.joint_provider)
00499 self.controller_manager = ControllerManager()
00500 self.sound = SoundPlay()
00501
00502 if use_projector:
00503 self.projector = StructuredLightProjector()
00504
00505 def pose(self):
00506 s = self.joint_provider()
00507 return {'larm': self.left.pose(s), 'rarm': self.right.pose(s), 'head_traj': self.head.pose(s)}
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633