00001
00002
00003
00004 import roslib
00005 roslib.load_manifest('pr2_simple_interface')
00006 import rospy
00007 import actionlib
00008 import math
00009 import random
00010
00011 from pr2_controllers_msgs.msg import *
00012 from pr2_gripper_sensor_msgs.msg import *
00013 from pr2_controllers_msgs.msg import *
00014 from trajectory_msgs.msg import *
00015 from sensor_msgs.msg import *
00016 from sound_play.msg import SoundRequest
00017 from sound_play.libsoundplay import SoundClient
00018 from face_detector.msg import *
00019 import std_srvs.srv
00020
00021
00022 LEFT = 1
00023 RIGHT = 2
00024 BOTH = 3
00025
00026 def convert_s(s):
00027 if (s == LEFT):
00028 return "left"
00029 if (s == RIGHT):
00030 return "right"
00031 if (s == BOTH):
00032 return "both"
00033 return "ERROR"
00034
00035 def pose_(position, joints, client, dur):
00036 goal = JointTrajectoryGoal()
00037 goal.trajectory.joint_names = joints
00038
00039 goal.trajectory.points = [ JointTrajectoryPoint() ]
00040
00041 goal.trajectory.points[0].velocities = [0.0] * len(joints);
00042 goal.trajectory.points[0].positions = position;
00043 goal.trajectory.points[0].time_from_start = rospy.Duration.from_sec(dur)
00044 client.send_goal(goal)
00045
00046 def pose_r(position, dur):
00047 joints = ["r_shoulder_pan_joint", "r_shoulder_lift_joint", "r_upper_arm_roll_joint", "r_elbow_flex_joint", "r_forearm_roll_joint", "r_wrist_flex_joint", "r_wrist_roll_joint"]
00048 pose_(position, joints, traj_client_r, dur)
00049
00050 def pose_l(position, dur):
00051 joints = ["l_shoulder_pan_joint", "l_shoulder_lift_joint", "l_upper_arm_roll_joint", "l_elbow_flex_joint", "l_forearm_roll_joint", "l_wrist_flex_joint", "l_wrist_roll_joint"]
00052 pose_(position, joints, traj_client_l, dur)
00053
00054 def pose_head(position, dur):
00055 joints = [ 'head_pan_joint', 'head_tilt_joint' ]
00056 pose_(position, joints, traj_client_head, dur)
00057
00058 def pose_torso(position, dur):
00059 joints = [ 'torso_lift_joint' ]
00060 pose_(position, joints, traj_client_torso, dur)
00061
00062 def actionClient(topic, t):
00063 if debug:
00064 print t
00065 c = actionlib.SimpleActionClient(topic, t)
00066 c.wait_for_server()
00067 return c
00068
00069 def TrajClient(t):
00070 return actionClient(t, JointTrajectoryAction)
00071
00072 def GripperClient(t):
00073 return actionClient(t, Pr2GripperCommandAction)
00074
00075 class Gripper:
00076 def __init__(self):
00077 pass
00078
00079
00080 def rel(self, s):
00081 print "Please use gripper.release() instead of gripper.rel()"
00082 self.release(s)
00083
00084
00085 def release(self, s):
00086 print "Release gripper:", convert_s(s)
00087 self.pose(s, 0.09)
00088
00089
00090 def pose(self, s, pos):
00091 if pos < 0:
00092 pos = 0
00093 if pos > 0.09:
00094 pos = 0.09
00095
00096 print "Set gripper %s to %d"%(convert_s(s), pos)
00097 openg = Pr2GripperCommandGoal()
00098 openg.command.position = pos
00099 openg.command.max_effort = -1.0
00100 if(s == LEFT or s == BOTH):
00101 gripper_client_l.send_goal(openg)
00102 if(s == RIGHT or s == BOTH):
00103 gripper_client_r.send_goal(openg)
00104
00105
00106 def close(self, s):
00107 print "Close gripper:", convert_s(s)
00108 self.pose(s, 0.002)
00109
00110
00111 def wait_for(self, s):
00112 if(s == LEFT or s == BOTH):
00113 gripper_client_l.wait_for_result()
00114 if(s == RIGHT or s == BOTH):
00115 gripper_client_r.wait_for_result()
00116
00117 def slap(self, s):
00118 place_goal = PR2GripperEventDetectorGoal()
00119 place_goal.command.trigger_conditions = 4
00120 place_goal.command.acceleration_trigger_magnitude = 6.0
00121 place_goal.command.slip_trigger_magnitude = 0.008
00122
00123 if sim:
00124 rospy.sleep(1)
00125 print "Simulating a slap"
00126 self.rel(s)
00127 else:
00128 if(s == LEFT or s == BOTH):
00129 place_client_l.send_goal(place_goal)
00130 if(s == RIGHT or s == BOTH):
00131 place_client_r.send_goal(place_goal)
00132
00133
00134 def slapDone(self, s):
00135 if sim:
00136 print "slapDone always true in simulation"
00137 return True
00138 else:
00139 SUCCEEDED = 3
00140 if(s == BOTH):
00141 return place_client_l.get_state() == SUCCEEDED and place_client_r.get_state() == SUCCEEDED
00142 elif(s == LEFT):
00143 return place_client_l.get_state() == SUCCEEDED
00144 elif(s == RIGHT):
00145 return place_client_r.get_state() == SUCCEEDED
00146 return False
00147
00148 def wait_for_slap(self, s):
00149 print "Wait for slap: ", convert_s(s)
00150 self.slap(s)
00151 while not self.slapDone(s):
00152 rospy.sleep(0.01)
00153
00154 def determine_slap(self):
00155 print "Determine which arm is slapped"
00156 self.slap(BOTH)
00157 while True:
00158 if (self.slapDone(LEFT)):
00159 print "Left arm slapped"
00160 return LEFT
00161 if (self.slapDone(RIGHT)):
00162 print "Right arm slapped"
00163 return RIGHT
00164 rospy.sleep(0.01)
00165
00166
00167 class RobotArm:
00168 def __init__(self):
00169 self.l = [ 0, 0, 0, 0, 0, 0, 0]
00170 self.r = [ 0, 0, 0, 0, 0, 0, 0]
00171 self.dur = 2.0
00172 pass
00173
00174 def move_to(self, goal, s, dur=2.0):
00175 positions = [ a * math.pi / 180.0 for a in goal ]
00176 if (s == RIGHT):
00177 print "Moving right arm to:", goal
00178 self.r = positions
00179 self.dur = dur
00180 pose_r(positions, dur)
00181 arm = True
00182 if (s == LEFT):
00183 print "Moving left arm to:", goal
00184 self.l = positions
00185 self.dur = dur
00186 pose_l(positions, dur)
00187 if (s == BOTH):
00188 print "WARNING: you can't send a goal of both to the arms"
00189
00190 def wait_for(self, s):
00191 print "Wait for arm:", convert_s(s)
00192 if (s == LEFT or s == BOTH):
00193 traj_client_l.wait_for_result()
00194 if (s == RIGHT or s == BOTH):
00195 traj_client_r.wait_for_result()
00196
00197 def mirror(self, s):
00198 if ( s == RIGHT ):
00199 print "Left arm mirroring right arm"
00200 positions = self.r
00201 for i in [0, 2, 4, 6]:
00202 positions[i] = -positions[i]
00203 pose_l(positions, self.dur)
00204 if ( s == LEFT ):
00205 print "Right arm mirroring left arm"
00206 positions = self.l
00207 for i in [0, 2, 4, 6]:
00208 positions[i] = -positions[i]
00209 pose_r(positions, self.dur)
00210
00211
00212 class Head:
00213 def __init__(self):
00214 self.mode = 0
00215 pass
00216
00217 def look_at(self, x, y, z, dur=1.0):
00218 print "Look at:", x, y, z
00219 g = PointHeadGoal()
00220 g.target.header.frame_id = 'base_link'
00221 g.target.point.x = x
00222 g.target.point.y = y
00223 g.target.point.z = z
00224 g.min_duration = rospy.Duration(dur)
00225 head_client.send_goal(g)
00226 self.mode = 1
00227
00228 def look(self, x, y, dur=1.0):
00229 pose = [ x * math.pi / 180.0, y * math.pi / 180.0 ]
00230 print "Look: ", pose
00231 pose_head(pose, dur)
00232 self.mode = 2
00233
00234 def look_at_face(self):
00235 print "Looking at a face"
00236 if sim:
00237 g = PointHeadGoal()
00238 g.target.header.frame_id = 'base_link'
00239 g.target.point.x = 2.0
00240 g.target.point.y = 0.25
00241 g.target.point.z = 1.5
00242 g.min_duration = rospy.Duration(1.0)
00243 head_client.send_goal(g)
00244 self.mode = 1
00245 else:
00246 fgoal = FaceDetectorGoal()
00247 nfaces = 0
00248 closest = -1
00249 closest_dist = 1000
00250 while nfaces < 1:
00251 face_client.send_goal(fgoal)
00252 face_client.wait_for_result()
00253 f = face_client.get_result()
00254 nfaces = len(f.face_positions)
00255
00256 for i in range(nfaces):
00257 dist = f.face_positions[i].pos.x*f.face_positions[i].pos.x + f.face_positions[i].pos.y*f.face_positions[i].pos.y\
00258 + f.face_positions[i].pos.z*f.face_positions[i].pos.z
00259 if dist < closest_dist:
00260 closest = i
00261 closest_dist = dist
00262
00263 if closest > -1:
00264 g = PointHeadGoal()
00265 g.target.header.frame_id = f.face_positions[closest].header.frame_id
00266 g.target.point.x = f.face_positions[closest].pos.x
00267 g.target.point.y = f.face_positions[closest].pos.y
00268 g.target.point.z = f.face_positions[closest].pos.z
00269 g.min_duration = rospy.Duration(1.0)
00270 head_client.send_goal(g)
00271 self.mode = 1
00272
00273
00274 def random_look_at_face(self):
00275 print "Looking at a face"
00276 if sim:
00277 g = PointHeadGoal()
00278 g.target.header.frame_id = 'base_link'
00279 g.target.point.x = 2.0
00280 g.target.point.y = 0.25
00281 g.target.point.z = 1.5
00282 g.min_duration = rospy.Duration(1.0)
00283 head_client.send_goal(g)
00284 self.mode = 1
00285 else:
00286 fgoal = FaceDetectorGoal()
00287 nfaces = 0
00288 closest = -1
00289 closest_dist = 1000
00290 while nfaces < 1:
00291 face_client.send_goal(fgoal)
00292 face_client.wait_for_result()
00293 f = face_client.get_result()
00294 nfaces = len(f.face_positions)
00295
00296 iter = 0
00297 while iter < 10 and closest <= -1:
00298 iter = iter + 1
00299 i = random.randrange(0,nfaces)
00300
00301 dist = f.face_positions[i].pos.x*f.face_positions[i].pos.x + f.face_positions[i].pos.y*f.face_positions[i].pos.y\
00302 + f.face_positions[i].pos.z*f.face_positions[i].pos.z
00303 print "This face has position and dist ", f.face_positions[i].pos.x, f.face_positions[i].pos.y, f.face_positions[i].pos.z, dist
00304 if dist < closest_dist and f.face_positions[i].pos.y > -1.0 :
00305 closest = i
00306 closest_dist = dist
00307 break
00308
00309 if closest > -1:
00310 print "Turning to face ", f.face_positions[closest].pos.x, f.face_positions[closest].pos.y, f.face_positions[closest].pos.z
00311 g = PointHeadGoal()
00312 g.target.header.frame_id = f.face_positions[closest].header.frame_id
00313 g.target.point.x = f.face_positions[closest].pos.x
00314 g.target.point.y = f.face_positions[closest].pos.y
00315 g.target.point.z = f.face_positions[closest].pos.z
00316 g.min_duration = rospy.Duration(1.0)
00317 head_client.send_goal(g)
00318 self.mode = 1
00319
00320
00321 def wait_for(self):
00322 print "Wait for head positioning"
00323 if self.mode == 1:
00324 head_client.wait_for_result()
00325 if self.mode == 2:
00326 traj_client_head.wait_for_result()
00327 self.mode = 0
00328
00329
00330 class Torso:
00331 def __init__(self):
00332 pass
00333
00334 def set(self, h, dur=10.0):
00335 if h > 0.3:
00336 h = 0.3
00337 if h < 0:
00338 h = 0
00339 print "Setting torso height to", h
00340 pose_torso([h], dur)
00341
00342 def wait_for(self):
00343 print "Waiting for torso"
00344 traj_client_torso.wait_for_result();
00345
00346 class Sound(SoundClient):
00347 def __init__(self):
00348 if debug:
00349 print "Initializing Sound Client"
00350 SoundClient.__init__(self)
00351
00352 timeout = 10
00353 while timeout > 0:
00354 if self.pub.get_num_connections() > 0:
00355 timeout = 0
00356 else:
00357 rospy.sleep(1)
00358
00359 def say(self, text):
00360 print "Saying: \"%s\""%text
00361 SoundClient.say(self, text)
00362
00363 def hug():
00364 rospy.wait_for_service('/pr2_props/hug')
00365 hug_client = rospy.ServiceProxy('/pr2_props/hug', std_srvs.srv.Empty)
00366 try:
00367 hug_client()
00368 print "Hug successful!"
00369 except rospy.ServiceException, e:
00370 print "Hug service call failed"
00371
00372
00373 def start(d = False):
00374 global debug
00375 debug = d
00376 if debug:
00377 print "Initializing pr2_simple_interface"
00378 rospy.init_node('pr2_simple_interface')
00379
00380 global traj_client_r
00381 global traj_client_l
00382 global place_client_r
00383 global place_client_l
00384 traj_client_r = TrajClient("r_arm_controller/joint_trajectory_action")
00385 traj_client_l = TrajClient("l_arm_controller/joint_trajectory_action")
00386
00387 global gripper_client_l
00388 global gripper_client_r
00389 global sim
00390
00391 if( not rospy.has_param('gazebo') ):
00392 gripper_client_l = GripperClient("l_gripper_sensor_controller/gripper_action")
00393 gripper_client_r = GripperClient("r_gripper_sensor_controller/gripper_action")
00394 place_client_l = actionClient("l_gripper_sensor_controller/event_detector", PR2GripperEventDetectorAction)
00395 place_client_r = actionClient("r_gripper_sensor_controller/event_detector", PR2GripperEventDetectorAction)
00396 sim = False
00397 else:
00398 gripper_client_l = GripperClient("l_gripper_controller/gripper_action")
00399 gripper_client_r = GripperClient("r_gripper_controller/gripper_action")
00400 sim = True
00401
00402 global face_client
00403 face_client = actionClient('face_detector_action',FaceDetectorAction)
00404
00405 global head_client
00406 head_client = actionClient('/head_traj_controller/point_head_action', PointHeadAction)
00407
00408 global traj_client_torso
00409 traj_client_torso = TrajClient('torso_controller/joint_trajectory_action')
00410
00411 global traj_client_head
00412 traj_client_head = TrajClient('head_traj_controller/joint_trajectory_action')
00413
00414
00415 if debug:
00416 print "pr2_simple_interface init done"