pr2_touch_simple.py
Go to the documentation of this file.
00001 #! /usr/bin/python
00002 
00003 import sys
00004 import numpy as np
00005 
00006 import roslib
00007 roslib.load_manifest('hrl_pr2_arms')
00008 roslib.load_manifest('smach_ros')
00009 roslib.load_manifest('actionlib')
00010 import rospy
00011 
00012 import smach
00013 from smach_ros import SimpleActionState, ServiceState, IntrospectionServer
00014 import actionlib
00015 import tf
00016 import tf.transformations as tf_trans
00017 from std_msgs.msg import Bool, Float32
00018 from std_srvs.srv import Empty
00019 from geometry_msgs.msg import PoseStamped, Vector3
00020 from actionlib_msgs.msg import GoalStatus
00021 
00022 #from hrl_trajectory_playback.srv import TrajPlaybackSrv, TrajPlaybackSrvRequest
00023 from hrl_generic_arms.pose_converter import PoseConverter
00024 from hrl_pr2_arms.pr2_arm import create_pr2_arm
00025 from hrl_pr2_arms.pr2_arm_hybrid import PR2ArmHybridForce
00026 
00027 class ClickMonitor(smach.State):
00028     def __init__(self):
00029         smach.State.__init__(self, outcomes=['click', 'shutdown'],
00030                                    output_keys=['click_pose'])
00031         self.cur_msg = None
00032         rospy.Subscriber('/pixel3d', PoseStamped, self.click_cb)
00033 
00034     def click_cb(self, msg):
00035         self.cur_msg = msg
00036 
00037     def execute(self, userdata):
00038         self.cur_msg = None
00039         while not rospy.is_shutdown():
00040             if self.cur_msg is not None:
00041                 userdata.click_pose = self.cur_msg
00042                 return 'click'
00043             rospy.sleep(0.01)
00044         return 'shutdown'
00045 
00046 class TFPubLoop(object):
00047     def __init__(self, parent_frame_name, child_frame_name, rate=100):
00048         self.child_frame_name = child_frame_name
00049         self.parent_frame_name = parent_frame_name
00050         self.tf_broad = tf.TransformBroadcaster()
00051         self.timer = rospy.Timer(rospy.Duration(1. / rate), self.pub_tf)
00052         self.tf_pose = None
00053 
00054     def pub_tf(self, timer_info):
00055         if self.tf_pose is not None:
00056             self.tf_broad.sendTransform(self.tf_pose[0], self.tf_pose[1], rospy.Time.now(), 
00057                                         self.child_frame_name, self.parent_frame_name)
00058 
00059     def update_pose(self, pose):
00060         self.tf_pose = PoseConverter.to_pos_quat(pose)
00061         self.pub_tf(None)
00062         
00063 class SMTouchSimple(object):
00064     def __init__(self):
00065         self.tf_listener = tf.TransformListener()
00066         self.start_frame_pub = rospy.Publisher("~start_frame", PoseStamped)
00067         self.end_frame_pub = rospy.Publisher("~end_frame", PoseStamped)
00068 
00069         self.arm = create_pr2_arm('l', PR2ArmHybridForce)
00070         self.tf_pub = TFPubLoop("/torso_lift_link", "/contact_control_frame")
00071 
00072     def get_transform(self, from_frame, to_frame, time=None):
00073         if time is None:
00074             time = rospy.Time.now()
00075         try:
00076             self.tf_listener.waitForTransform(from_frame, to_frame, time, rospy.Duration(5))
00077             pos, quat = self.tf_listener.lookupTransform(from_frame, to_frame, time)
00078             return util.pose_pq_to_mat(pos, quat)
00079         except (tf.Exception, tf.LookupException, tf.ConnectivityException):
00080             return None
00081 
00082     def get_trajectory_generator(self):
00083         
00084         @smach.cb_interface(input_keys=['start_click', 'end_click'],
00085                             output_keys=['start_traj_frame', 'end_traj_frame'],
00086                             outcomes=['succeeded'])
00087         def generate_trajectory(ud):
00088             b_B_s = PoseConverter.to_homo_mat(ud.start_click)
00089             b_B_e = PoseConverter.to_homo_mat(ud.end_click)
00090             s_B_e = (b_B_s ** -1) * b_B_e
00091             b_normal = b_B_s[:3, 2] / np.linalg.norm(b_B_s[:3, 2])
00092             s_vel = np.mat([s_B_e[0, 3], s_B_e[1, 3], 0]).T
00093             s_vel = s_vel / np.linalg.norm(s_vel)
00094             b_vel = b_B_s[:3, :3].T * s_vel
00095             b_ortho = np.mat(np.cross(b_normal.T, b_vel.T)).T
00096             b_ortho = b_ortho /  np.linalg.norm(b_ortho)
00097             b_R_traj = np.vstack([b_vel.T, b_ortho.T, b_normal.T])
00098 
00099             b_p_start = b_B_s[:3, 3]
00100             b_p_end = b_B_e[:3, 3]
00101             b_p_end = 3 #TODO TODO
00102             
00103             self.start_frame_pub.publish(PoseConverter.to_pose_stamped_msg(ud.start_click.header.frame_id, 
00104                                                                            (b_p_start, b_R_traj)))
00105             self.end_frame_pub.publish(PoseConverter.to_pose_stamped_msg(ud.start_click.header.frame_id, 
00106                                                                          (b_p_end, b_R_traj)))
00107             
00108 
00109             ud.start_traj_frame = (b_p_start, b_R_traj)
00110             ud.end_traj_frame = (b_p_end, b_R_traj)
00111             return 'succeeded'
00112 
00113         return smach.CBState(generate_trajectory)
00114             
00115 
00116     def get_sm(self):
00117         sm = smach.StateMachine(outcomes=['succeeded','preempted','shutdown'])
00118         
00119         with sm:
00120             smach.StateMachine.add(
00121                 'INPUT_START_CLICK',
00122                 ClickMonitor(),
00123                 transitions={'click' : 'INPUT_END_CLICK',
00124                              'shutdown' : 'shutdown'},
00125                 remapping={'click_pose' : 'start_click'}) # output (PoseStamped)
00126 
00127             smach.StateMachine.add(
00128                 'INPUT_END_CLICK',
00129                 ClickMonitor(),
00130                 transitions={'click' : 'GENERATE_TRAJECTORY',
00131                              'shutdown' : 'shutdown'},
00132                 remapping={'click_pose' : 'end_click'}) # output (PoseStamped)
00133 
00134             smach.StateMachine.add(
00135                 'GENERATE_TRAJECTORY',
00136                 self.get_trajectory_generator(),
00137                 transitions={'succeeded' : 'INPUT_START_CLICK'})
00138 
00139         return sm
00140 
00141     def get_sm_basic(self):
00142         sm = smach.StateMachine(outcomes=['succeeded','preempted','shutdown'])
00143         
00144         with sm:
00145             smach.StateMachine.add(
00146                 'INPUT_START_CLICK',
00147                 ClickMonitor(),
00148                 transitions={'click' : 'PUBLISH_CONTROL_FRAME',
00149                              'shutdown' : 'shutdown'},
00150                 remapping={'click_pose' : 'start_click'}) # output (PoseStamped)
00151 
00152             @smach.cb_interface(input_keys=['start_click'],
00153                                 outcomes=['succeeded', 'failed'])
00154             def publish_control_frame(ud):
00155                 if ud.start_click.pose.position.x == -10000.0:
00156                     return 'failed'
00157                 pose = ud.start_click
00158                 pose.header.stamp = rospy.Time(0)
00159                 click_torso = self.tf_listener.transformPose("/torso_lift_link", pose)
00160                 self.tf_pub.update_pose(click_torso)
00161                 rospy.sleep(1)
00162                 self.arm.set_tip_frame("/contact_control_frame")
00163 #self.arm.set_motion_gains(p_trans=[300, 300, 100])
00164                 self.arm.update_gains()
00165                 return 'succeeded'
00166             smach.StateMachine.add(
00167                 'PUBLISH_CONTROL_FRAME',
00168                 smach.CBState(publish_control_frame),
00169                 transitions={'succeeded' : 'INPUT_START_CLICK',
00170                              'failed' : 'INPUT_START_CLICK'})
00171 
00172         return sm
00173 
00174 
00175 def main():
00176     rospy.init_node('pr2_touch_simple')
00177     smts = SMTouchSimple()
00178     sm = smts.get_sm_basic()
00179     rospy.sleep(1)
00180 
00181     sis = IntrospectionServer('touch_simple', sm, '/INPUT_START_CLICK')
00182     sis.start()
00183 
00184     outcome = sm.execute()
00185     
00186     sis.stop()
00187 
00188 if __name__ == '__main__':
00189     main()


hrl_phri_2011
Author(s): Kelsey Hawkins
autogenerated on Wed Nov 27 2013 12:22:40