00001 import rcommander.tool_utils as tu
00002 import tf_utils as tfu
00003 import pr2_utils as p2u
00004
00005 from PyQt4.QtGui import *
00006 from PyQt4.QtCore import *
00007
00008 import rospy
00009 import geometry_msgs.msg as geo
00010 import tf.transformations as tr
00011 import smach
00012 from object_manipulator.convert_functions import *
00013
00014 import numpy as np
00015 import math
00016 import threading
00017 import time
00018
00019 def pose_distance(ps_a, ps_b, tflistener):
00020
00021 ps_a_fb = change_pose_stamped_frame(tflistener, ps_a, ps_b.header.frame_id)
00022 g_T_a = pose_to_mat(ps_a_fb.pose)
00023 g_T_b = pose_to_mat(ps_b.pose)
00024
00025 a_T_b = g_T_a**-1 * g_T_b
00026
00027 desired_trans = a_T_b[0:3, 3].copy()
00028 a_T_b[0:3, 3] = 0
00029 desired_angle, desired_axis, _ = tf.transformations.rotation_from_matrix(a_T_b)
00030 return desired_trans, desired_angle, desired_axis
00031
00032
00033 class VelocityPriorityMoveTool(tu.ToolBase, p2u.SE3Tool):
00034
00035 LEFT_CONTROL_FRAME = rospy.get_param('/l_cart/tip_name')
00036 RIGHT_CONTROL_FRAME = rospy.get_param('/r_cart/tip_name')
00037 LEFT_TIP = '/l_gripper_tool_frame'
00038 RIGHT_TIP = '/r_gripper_tool_frame'
00039 MIN_TIME = .01
00040 COMMAND_FRAME = '/torso_lift_link'
00041
00042 def __init__(self, rcommander):
00043 p2u.SE3Tool.__init__(self)
00044 tu.ToolBase.__init__(self, rcommander, 'velocity_priority', 'Velocity Priority', VelocityPriorityState)
00045 self.default_frame = '/torso_lift_link'
00046 self.tf_listener = rcommander.tf_listener
00047
00048 def fill_property_box(self, pbox):
00049 formlayout = pbox.layout()
00050 frame_box = self.make_task_frame_box(pbox)
00051 group_boxes = self.make_se3_boxes(pbox)
00052 self.arm_radio_boxes, self.arm_radio_buttons = tu.make_radio_box(pbox, ['Left', 'Right'], 'arm')
00053 self.list_manager = p2u.ListManager(self.get_current_data_cb, self.set_current_data_cb, None, name_preffix='point')
00054 list_widgets = self.list_manager.make_widgets(pbox, self.rcommander)
00055
00056 self.pose_button = QPushButton(pbox)
00057 self.pose_button.setText('Current Pose')
00058 self.rcommander.connect(self.pose_button, SIGNAL('clicked()'), self.get_current_pose)
00059 self.time_box = QDoubleSpinBox(pbox)
00060
00061 self.time_box.setMinimum(0)
00062 self.time_box.setMaximum(1000.)
00063 self.time_box.setSingleStep(.1)
00064
00065 formlayout.addRow('&Frame', frame_box)
00066 formlayout.addRow('&Arm', self.arm_radio_boxes)
00067 formlayout.addRow('&Duration', self.time_box)
00068
00069 for gb in group_boxes:
00070 formlayout.addRow(gb)
00071
00072 formlayout.addRow(self.pose_button)
00073
00074 for gb in list_widgets:
00075 formlayout.addRow(gb)
00076 self.reset()
00077
00078 def get_current_pose(self):
00079 frame_described_in = str(self.frame_box.currentText())
00080 arm = tu.selected_radio_button(self.arm_radio_buttons).lower()
00081 if arm == 'right':
00082 arm_tip_frame = VelocityPriorityMoveTool.RIGHT_TIP
00083 else:
00084 arm_tip_frame = VelocityPriorityMoveTool.LEFT_TIP
00085 self.tf_listener.waitForTransform(frame_described_in, arm_tip_frame, rospy.Time(), rospy.Duration(2.))
00086 p_arm = tfu.tf_as_matrix(self.tf_listener.lookupTransform(frame_described_in, arm_tip_frame, rospy.Time(0)))
00087 trans, rotation = tr.translation_from_matrix(p_arm), tr.quaternion_from_matrix(p_arm)
00088 for value, vr in zip(trans, [self.xline, self.yline, self.zline]):
00089 vr.setValue(value)
00090 for value, vr in zip(tr.euler_from_quaternion(rotation), [self.phi_line, self.theta_line, self.psi_line]):
00091 vr.setValue(np.degrees(value))
00092
00093 def get_current_data_cb(self):
00094 arm = tu.selected_radio_button(self.arm_radio_buttons).lower()
00095 posestamped = self.get_posestamped()
00096 t = self.time_box.value()
00097 return {'arm': arm, 'pose_stamped': posestamped, 'time': t}
00098
00099 def set_current_data_cb(self, data):
00100 if 'left' == data['arm']:
00101 self.arm_radio_buttons[0].setChecked(True)
00102 if data['arm'] == 'right':
00103 self.arm_radio_buttons[1].setChecked(True)
00104 self.set_posestamped(data['pose_stamped'])
00105 self.time_box.setValue(data['time'])
00106
00107 def new_node(self, name=None):
00108 if name == None:
00109 nname = self.name + str(self.counter)
00110 else:
00111 nname = name
00112 self
00113 return VelocityPriorityState(nname, self.list_manager.get_data())
00114
00115 def set_node_properties(self, node):
00116 self.list_manager.set_data(node.pose_stamps_list)
00117 self.list_manager.select_default_item()
00118
00119 def reset(self):
00120 self.arm_radio_buttons[0].setChecked(True)
00121 for vr in [self.xline, self.yline, self.zline, self.phi_line, self.theta_line, self.psi_line]:
00122 vr.setValue(0.0)
00123 self.frame_box.setCurrentIndex(self.frame_box.findText(self.default_frame))
00124
00125 self.time_box.setValue(0.5)
00126 self.list_manager.set_default_selection()
00127
00128
00129 class VelocityPriorityState(tu.StateBase):
00130
00131 def __init__(self, name,
00132 pose_stamps_list):
00133 tu.StateBase.__init__(self, name)
00134 self.pose_stamps_list = pose_stamps_list
00135
00136 def get_smach_state(self):
00137
00138 return VelocityPriorityStateSmach([p['data'] for p in self.pose_stamps_list])
00139
00140
00141 class PlayTrajectory(threading.Thread):
00142
00143 def __init__(self, cart_pub, messages, controller_frame, tip_frame, tf_listener):
00144 threading.Thread.__init__(self)
00145 self.cart_pub = cart_pub
00146 self.messages = messages
00147 self.stop = False
00148 self.controller_frame = controller_frame
00149 self.tip_frame = tip_frame
00150 self.tf_listener = tf_listener
00151
00152 def set_stop(self):
00153 self.stop = True
00154
00155 def run(self):
00156
00157 if len(self.messages) == 0:
00158 return
00159 timeslp = [0.0]
00160 for idx, message in enumerate(self.messages[1:]):
00161 timeslp.append(message['time'] + timeslp[idx])
00162
00163 current_pose = tfu.tf_as_matrix(self.tf_listener.lookupTransform(VelocityPriorityMoveTool.COMMAND_FRAME,
00164 self.controller_frame, rospy.Time(0)))
00165
00166 wall_start_time = rospy.get_rostime().to_time()
00167 for t, el in zip(timeslp, self.messages):
00168
00169 cur_time = rospy.get_rostime().to_time()
00170 wall_time_from_start = cur_time - wall_start_time
00171 sleep_time = (t - wall_time_from_start) - .005
00172
00173 if sleep_time > 0:
00174 time.sleep(sleep_time)
00175
00176 if self.stop:
00177 return
00178
00179
00180
00181 tip_torso = change_pose_stamped_frame(self.tf_listener,
00182 el['pose_stamped'], VelocityPriorityMoveTool.COMMAND_FRAME)
00183 tll_T_tip = pose_to_mat(tip_torso.pose)
00184
00185 tip_T_wrist = tfu.tf_as_matrix(self.tf_listener.lookupTransform(self.tip_frame, self.controller_frame, rospy.Time(0)))
00186
00187 tll_T_wrist = tll_T_tip * tip_T_wrist
00188
00189 wrist_torso = stamp_pose(mat_to_pose(tll_T_wrist), 'torso_lift_link')
00190
00191
00192
00193
00194 self.cart_pub.publish(wrist_torso)
00195
00196
00197 class VelocityPriorityStateSmach(smach.State):
00198
00199 LEFT_CONTROL_FRAME = rospy.get_param('/l_cart/tip_name')
00200 RIGHT_CONTROL_FRAME = rospy.get_param('/r_cart/tip_name')
00201
00202
00203 def __init__(self, poses_list):
00204 smach.State.__init__(self, outcomes = ['succeeded', 'preempted', 'failed'],
00205 input_keys = [], output_keys = [])
00206
00207
00208 self.poses_list = poses_list
00209 self.lcart = rospy.Publisher('/l_cart/command_pose', geo.PoseStamped)
00210 self.rcart = rospy.Publisher('/r_cart/command_pose', geo.PoseStamped)
00211 self.robot = None
00212
00213 def set_robot(self, robot_obj):
00214 self.robot = robot_obj
00215
00216 def execute(self, userdata):
00217
00218 lp = []
00219 rp = []
00220 for p in self.poses_list:
00221
00222
00223 if p['arm'] == 'left':
00224 lp.append(p)
00225 else:
00226 rp.append(p)
00227
00228 lpthread = PlayTrajectory(self.lcart, lp, VelocityPriorityMoveTool.LEFT_CONTROL_FRAME,
00229 VelocityPriorityMoveTool.LEFT_TIP, self.robot.tf_listener)
00230 rpthread = PlayTrajectory(self.rcart, rp, VelocityPriorityMoveTool.RIGHT_CONTROL_FRAME,
00231 VelocityPriorityMoveTool.RIGHT_TIP, self.robot.tf_listener)
00232 lpthread.start()
00233 rpthread.start()
00234
00235 r = rospy.Rate(100)
00236 preempted = False
00237 finished = False
00238 while not finished:
00239
00240 if self.preempt_requested():
00241 rospy.loginfo('VelocityPriorityStateSmach: preempt requested')
00242
00243 lpthread.stop()
00244 rpthread.stop()
00245 self.service_preempt()
00246 preempted = True
00247 break
00248
00249 if not lpthread.is_alive() and not rpthread.is_alive():
00250
00251
00252
00253
00254 finished = True
00255
00256 r.sleep()
00257
00258 if preempted:
00259 return 'preempted'
00260
00261 if finished:
00262 return 'succeeded'
00263
00264 return 'failed'
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278