00001
00002 import rcommander.tool_utils as tu
00003
00004 from PyQt4.QtGui import *
00005 from PyQt4.QtCore import *
00006 import rospy
00007 import tf_utils as tfu
00008 import tf.transformations as tr
00009 import numpy as np
00010 from object_manipulator.convert_functions import *
00011 import ptp_arm_action.msg as ptp
00012 import math
00013 import geometry_msgs.msg as geo
00014 import actionlib
00015 import smach
00016 import actionlib_msgs.msg as am
00017 import pr2_utils as p2u
00018 from tf_broadcast_server.srv import BroadcastTransform, GetTransforms
00019
00020 class PositionPriorityMoveTool(tu.ToolBase, p2u.SE3Tool):
00021
00022 LEFT_TIP = '/l_gripper_tool_frame'
00023 RIGHT_TIP = '/r_gripper_tool_frame'
00024
00025
00026
00027 def __init__(self, rcommander):
00028 tu.ToolBase.__init__(self, rcommander, 'position_priority', 'Position Priority', PositionPriorityState)
00029 p2u.SE3Tool.__init__(self)
00030 self.default_frame = '/torso_lift_link'
00031 self.tf_listener = rcommander.tf_listener
00032
00033
00034
00035 def fill_property_box(self, pbox):
00036 formlayout = pbox.layout()
00037
00038 frame_box = self.make_task_frame_box(pbox)
00039 self.trans_vel_line = tu.double_spin_box(pbox, 0, 1., .02)
00040 self.rot_vel_line = tu.double_spin_box(pbox, 0, np.pi, .02)
00041 group_boxes = self.make_se3_boxes(pbox)
00042
00043 self.arm_radio_boxes, self.arm_radio_buttons = tu.make_radio_box(pbox, ['Left', 'Right'], 'arm')
00044 self.timeout_box = QDoubleSpinBox(pbox)
00045 self.timeout_box.setMinimum(0)
00046 self.timeout_box.setMaximum(1000.)
00047 self.timeout_box.setSingleStep(.2)
00048 motion_box = QGroupBox('Motion', pbox)
00049 motion_layout = QFormLayout(motion_box)
00050 motion_box.setLayout(motion_layout)
00051 motion_layout.addRow('Speed', self.trans_vel_line)
00052 motion_layout.addRow('Speed (rotational)', self.rot_vel_line)
00053 motion_layout.addRow("&Arm", self.arm_radio_boxes)
00054 motion_layout.addRow('&Time Out', self.timeout_box)
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
00060
00061 formlayout.addRow('Frame', self.frame_box)
00062 formlayout.addRow(motion_box)
00063 formlayout.addRow(group_boxes[0])
00064 formlayout.addRow(group_boxes[1])
00065 formlayout.addRow(self.pose_button)
00066 self.reset()
00067
00068 def get_current_pose(self):
00069 frame_described_in = str(self.frame_box.currentText())
00070 arm = tu.selected_radio_button(self.arm_radio_buttons).lower()
00071 if arm == 'right':
00072 arm_tip_frame = PositionPriorityMoveTool.RIGHT_TIP
00073 else:
00074 arm_tip_frame = PositionPriorityMoveTool.LEFT_TIP
00075 self.tf_listener.waitForTransform(frame_described_in, arm_tip_frame, rospy.Time(), rospy.Duration(2.))
00076 p_arm = self.tf_listener.lookupTransform(frame_described_in, arm_tip_frame, rospy.Time(0))
00077
00078
00079 for value, vr in zip(p_arm[0], [self.xline, self.yline, self.zline]):
00080 vr.setValue(value)
00081 for value, vr in zip(tr.euler_from_quaternion(p_arm[1]), [self.phi_line, self.theta_line, self.psi_line]):
00082 vr.setValue(np.degrees(value))
00083
00084 def new_node(self, name=None):
00085
00086 if name == None:
00087 nname = self.name + str(self.counter)
00088 else:
00089 nname = name
00090
00091
00092 trans_vel = self.trans_vel_line.value()
00093 rot_vel = self.rot_vel_line.value()
00094 arm = tu.selected_radio_button(self.arm_radio_buttons).lower()
00095 frame = str(self.frame_box.currentText())
00096 timeout = self.timeout_box.value()
00097 pose_stamped = self.get_posestamped()
00098 return PositionPriorityState(nname, pose_stamped, trans_vel, rot_vel, arm, timeout)
00099
00100 def set_node_properties(self, node):
00101 self.set_posestamped(node.pose_stamped)
00102 self.trans_vel_line.setValue(node.trans_vel)
00103 self.rot_vel_line.setValue(node.rot_vel)
00104
00105 if node.arm == 'left':
00106 self.arm_radio_buttons[0].setChecked(True)
00107 if node.arm == 'right':
00108 self.arm_radio_buttons[1].setChecked(True)
00109
00110 self.frame_box.setCurrentIndex(self.frame_box.findText(str(node.pose_stamped.header.frame_id)))
00111 self.timeout_box.setValue(node.timeout)
00112
00113 def reset(self):
00114 self.frame_box.setCurrentIndex(self.frame_box.findText(self.default_frame))
00115 for vr in [self.xline, self.yline, self.zline, self.phi_line, self.theta_line, self.psi_line]:
00116 vr.setValue(0.0)
00117 self.trans_vel_line.setValue(.02)
00118 self.rot_vel_line.setValue(.16)
00119 self.timeout_box.setValue(20)
00120 self.arm_radio_buttons[0].setChecked(True)
00121
00122 class PositionPriorityState(tu.StateBase):
00123
00124 def __init__(self, name, pose_stamped, trans_vel, rot_vel, arm,
00125 timeout):
00126 tu.StateBase.__init__(self, name)
00127 self.pose_stamped = pose_stamped
00128 self.trans_vel = trans_vel
00129 self.rot_vel = rot_vel
00130
00131 self.arm = arm
00132
00133 self.timeout = timeout
00134
00135
00136 def get_smach_state(self):
00137 return PositionPrioritySmach(self.pose_stamped, self.trans_vel, self.rot_vel,
00138 self.arm,
00139
00140 self.timeout)
00141
00142 class PositionPrioritySmach(smach.State):
00143
00144 def __init__(self, pose_stamped, trans_vel, rot_vel, arm,
00145
00146 timeout):
00147 smach.State.__init__(self, outcomes = ['succeeded', 'preempted', 'failed'],
00148 input_keys = [], output_keys = [])
00149
00150 self.pose_stamped = pose_stamped
00151 self.trans_vel = trans_vel
00152 self.rot_vel = rot_vel
00153 self.action_client = actionlib.SimpleActionClient(arm + '_ptp', ptp.LinearMovementAction)
00154 self.timeout = timeout
00155
00156 def set_robot(self, robot_obj):
00157 if robot_obj != None:
00158 self.robot = robot_obj
00159
00160 def execute_goal(self, goal, timeout):
00161 self.action_client.send_goal(goal)
00162 succeeded = False
00163 preempted = False
00164 r = rospy.Rate(30)
00165 start_time = rospy.get_time()
00166
00167 while True:
00168
00169 if self.preempt_requested():
00170 rospy.loginfo('PositionPrioritySmach: preempt requested')
00171 self.action_client.cancel_goal()
00172 self.service_preempt()
00173 preempted = True
00174 break
00175
00176 if (rospy.get_time() - start_time) > timeout:
00177 self.action_client.cancel_goal()
00178 rospy.loginfo('PositionPrioritySmach: timed out!')
00179 succeeded = False
00180 break
00181
00182
00183 state = self.action_client.get_state()
00184 if (state not in [am.GoalStatus.ACTIVE, am.GoalStatus.PENDING]):
00185 if state == am.GoalStatus.SUCCEEDED:
00186 rospy.loginfo('PositionPrioritySmach: Succeeded!')
00187 succeeded = True
00188 break
00189
00190 r.sleep()
00191
00192 if preempted:
00193 return 'preempted'
00194
00195 if succeeded:
00196 return 'succeeded'
00197
00198 return 'failed'
00199
00200 def execute(self, userdata):
00201 goal = ptp.LinearMovementGoal()
00202 goal.goal = self.pose_stamped
00203 goal.trans_vel = self.trans_vel
00204 goal.rot_vel = self.rot_vel
00205 return self.execute_goal(goal, self.timeout)
00206