Go to the documentation of this file.00001
00002
00003 import sys
00004 from threading import Lock
00005
00006 import roslib; roslib.load_manifest('assistive_teleop')
00007 import rospy
00008 import actionlib
00009 from std_msgs.msg import String
00010 from geometry_msgs.msg import PoseStamped
00011 from trajectory_msgs.msg import JointTrajectory, JointTrajectoryPoint
00012 from kinematics_msgs.srv import (GetKinematicSolverInfo,
00013 GetPositionIK,
00014 GetPositionIKRequest)
00015 from pr2_controllers_msgs.msg import (JointTrajectoryAction,
00016 JointTrajectoryGoal,
00017 JointTrajectoryControllerState)
00018
00019 class IKGoalSender(object):
00020 """A class for performing IK with the PR2 """
00021 def __init__(self, arm):
00022 """Initialize IK Services, arm trajectory client, state, and
00023 feedback"""
00024 self.arm = arm
00025 self.joint_state_lock = Lock()
00026
00027 self.traj_client = actionlib.SimpleActionClient(self.arm[0]+
00028 '_arm_controller/joint_trajectory_action',
00029 JointTrajectoryAction)
00030 if not self.traj_client.wait_for_server(rospy.Duration(5)):
00031 rospy.loginfo('[IKGoalSender] Timed Out waiting for '+
00032 'JointTrajectoryAction Server')
00033
00034 prefix = 'pr2_'+self.arm+'_arm_kinematics/'
00035 try:
00036 rospy.loginfo('Waiting for IK services')
00037 rospy.wait_for_service(prefix+'get_ik_solver_info')
00038 rospy.wait_for_service(prefix+'get_ik')
00039 rospy.loginfo("Found IK services")
00040 self.ik_info_proxy = rospy.ServiceProxy(prefix+"get_ik_solver_info",
00041 GetKinematicSolverInfo)
00042 self.ik_info = self.ik_info_proxy().kinematic_solver_info
00043 self.ik_client = rospy.ServiceProxy(prefix+"get_ik",
00044 GetPositionIK,
00045 True)
00046 except:
00047 rospy.logerr("Could not find IK services")
00048
00049 self.log_pub = rospy.Publisher('log_out', String)
00050 self.joint_state = {'positions':[],'velocities':[]}
00051 self.joint_state_received = False
00052 self.joint_state_sub = rospy.Subscriber(self.arm[0]+
00053 '_arm_controller/state',
00054 JointTrajectoryControllerState,
00055 self.joint_state_cb)
00056 self.pose_sub = rospy.Subscriber('pose_in', PoseStamped, self.pose_cb)
00057
00058 def joint_state_cb(self, js_msg):
00059 """Update joint positions and velocities"""
00060 with self.joint_state_lock:
00061 self.joint_state['positions'] = js_msg.actual.positions[:]
00062 self.joint_state['velocities'] = js_msg.actual.velocities[:]
00063 self.joint_state_received = True
00064
00065 def pose_cb(self, ps):
00066 """ Perform IK for a goal pose, and send action goal if acheivable"""
00067 if not self.joint_state_received:
00068 rospy.loginfo('[IKGoalSender] No Joint State Received')
00069 return
00070 req = self.form_ik_request(ps)
00071 ik_goal = self.ik_client(req)
00072 if ik_goal.error_code.val == 1:
00073 traj_point = JointTrajectoryPoint()
00074 traj_point.positions = ik_goal.solution.joint_state.position
00075 traj_point.velocities = ik_goal.solution.joint_state.velocity
00076 traj_point.time_from_start = rospy.Duration(1)
00077
00078 traj = JointTrajectory()
00079 traj.joint_names = self.ik_info.joint_names
00080 traj.points.append(traj_point)
00081
00082 traj_goal = JointTrajectoryGoal()
00083 traj_goal.trajectory = traj
00084 self.traj_client.send_goal(traj_goal)
00085 else:
00086 rospy.loginfo('[IKGoalSender] IK Failed: Cannot reach goal')
00087 self.log_pub.publish(String('IK Failed: Cannot reach goal'))
00088
00089 def form_ik_request(self, ps):
00090 """Compose an IK request from ik solver info and pose goal"""
00091 req = GetPositionIKRequest()
00092 req.timeout = rospy.Duration(5)
00093 req.ik_request.ik_link_name = self.ik_info.link_names[-1]
00094 req.ik_request.pose_stamped = ps
00095 req.ik_request.ik_seed_state.joint_state.name = self.ik_info.joint_names
00096 with self.joint_state_lock:
00097 positions = self.joint_state['positions'][:]
00098 velocities = self.joint_state['velocities'][:]
00099 req.ik_request.ik_seed_state.joint_state.position = positions
00100 req.ik_request.ik_seed_state.joint_state.velocity = velocities
00101 return req
00102
00103 if __name__=='__main__':
00104 rospy.init_node('ik_goal_relay')
00105 sender = IKGoalSender(sys.argv[sys.argv.index('--arm')+1])
00106 rospy.spin()