move_tool.py
Go to the documentation of this file.
00001 import roslib; roslib.load_manifest('rcommander')
00002 import rospy
00003 from PyQt4.QtGui import *
00004 from PyQt4.QtCore import *
00005 import tool_utils as tu
00006 import pr2_utils as pu
00007 import numpy as np
00008 import actionlib_msgs.msg as am
00009 import smach
00010 
00011 
00012 class JointSequenceTool(tu.ToolBase):
00013 
00014     def __init__(self, rcommander):
00015         tu.ToolBase.__init__(self, rcommander, 'joint_sequence', 'Joint Sequence')
00016         self.joint_name_fields = ["shoulder_pan_joint", "shoulder_lift_joint", "upper_arm_roll_joint", 
00017                                   "elbow_flex_joint", "forearm_roll_joint", "wrist_flex_joint", "wrist_roll_joint"]
00018         self.joint_angs_list = None
00019 
00020     def fill_property_box(self, pbox):
00021         formlayout = pbox.layout()
00022         self.arm_box = QComboBox(pbox)
00023         self.arm_box.addItem('left')
00024         self.arm_box.addItem('right')
00025         formlayout.addRow('&Arm', self.arm_box)
00026 
00027         #Controls for displaying the current joint states
00028         for name in self.joint_name_fields:
00029             exec("self.%s = QLineEdit(pbox)" % name)
00030             exec("formlayout.addRow(\"&\" + name, self.%s)" % name)
00031 
00032         self.time_box = QDoubleSpinBox(pbox)
00033         self.time_box.setMinimum(0)
00034         self.time_box.setMaximum(1000.)
00035         self.time_box.setSingleStep(.2)
00036         self.time_box.setValue(1.)
00037         formlayout.addRow('&Time', self.time_box)
00038    
00039         #Controls for getting the current joint states
00040         self.joint_angs_list = []
00041         self.list_widget = QListWidget(pbox)
00042         self.rcommander.connect(self.list_widget, SIGNAL('itemSelectionChanged()'), self.item_selection_changed_cb)
00043         self.list_widget_buttons = QWidget(pbox)
00044         self.lbb_hlayout = QHBoxLayout(self.list_widget_buttons)
00045 
00046         self.add_joint_set_button = QPushButton(self.list_widget_buttons)
00047         self.add_joint_set_button.setText('Add')
00048         self.rcommander.connect(self.add_joint_set_button, SIGNAL('clicked()'), self.add_joint_set_cb)
00049 
00050         self.remove_joint_set_button = QPushButton(self.list_widget_buttons)
00051         self.remove_joint_set_button.setText('Remove')
00052         self.rcommander.connect(self.remove_joint_set_button, SIGNAL('clicked()'), self.remove_pose_cb)
00053 
00054         self.pose_button = QPushButton(self.list_widget_buttons)
00055         self.pose_button.setText('Pose')
00056         self.rcommander.connect(self.pose_button, SIGNAL('clicked()'), self.get_current_joint_angles)
00057 
00058         self.lbb_hlayout.addWidget(self.add_joint_set_button)
00059         self.lbb_hlayout.addWidget(self.remove_joint_set_button)
00060         self.lbb_hlayout.addWidget(self.pose_button)
00061         self.lbb_hlayout.setContentsMargins(2, 2, 2, 2)
00062 
00063         formlayout.addRow(self.list_widget)
00064         formlayout.addRow(self.list_widget_buttons)
00065         self.reset()
00066 
00067     def get_current_joint_angles(self):
00068         if ('left' == str(self.arm_box.currentText())):
00069             arm_obj = self.rcommander.pr2.left
00070         else:
00071             arm_obj = self.rcommander.pr2.right
00072 
00073         pose_mat = arm_obj.pose()
00074         for idx, name in enumerate(self.joint_name_fields):
00075             deg = np.degrees(pose_mat[idx, 0])
00076             exec('line_edit = self.%s' % name)
00077             line_edit.setText(str(deg))
00078 
00079     def _has_name(self, test_name):
00080         for rec in self.joint_angs_list:
00081             if rec['name'] == test_name:
00082                 return True
00083             else:
00084                 return False
00085 
00086     def _create_name(self):
00087         idx = len(self.joint_angs_list)
00088         tentative_name = 'point%d' % idx 
00089 
00090         while self._has_name(tentative_name):
00091             idx = idx + 1
00092             tentative_name = 'point%d' % idx 
00093 
00094         return tentative_name
00095 
00096     def item_selection_changed_cb(self):
00097         selected = self.list_widget.selectedItems()
00098         if len(selected) == 0:
00099             return
00100         idx = self._find_index_of(str(selected[0].text()))
00101         joint_angs = self.joint_angs_list[idx]['angs']
00102         self._set_joints_to_fields(joint_angs)
00103         self.time_box.setValue(self.joint_angs_list[idx]['time'])
00104 
00105     def add_joint_set_cb(self):
00106         #Create a new string, check to see whether it's in the current list
00107         name = self._create_name()
00108         self.list_widget.addItem(name)
00109         self.joint_angs_list.append({'name':name, 'time': self.time_box.value(), 'angs': self._read_joints_from_fields()})
00110 
00111     def _find_index_of(self, name):
00112         for idx, tup in enumerate(self.joint_angs_list):
00113             if tup['name'] == name:
00114                 return idx
00115         return None
00116 
00117     def remove_pose_cb(self):
00118         #Get currently selected
00119         selected = self.list_widget.selectedItems()
00120         if len(selected) == 0:
00121             return 
00122         sname = str(selected[0].text())
00123 
00124         #Remove it from list_widget and joint_angs_list
00125         idx = self._find_index_of(sname)
00126         self.list_widget.takeItem(idx)
00127         #self.list_widget.removeItemWidget(selected[0])
00128         if idx == None:
00129             raise RuntimeError('Inconsistency detected in list')
00130         else:
00131             self.joint_angs_list.pop(idx)
00132 
00133     def _read_joints_from_fields(self):
00134         joints = []
00135         for name in self.joint_name_fields:
00136             exec('rad = np.radians(float(str(self.%s.text())))' % name)
00137             joints.append(rad)
00138         return joints
00139 
00140     def _set_joints_to_fields(self, joints):
00141         for idx, name in enumerate(self.joint_name_fields):
00142             deg = np.degrees(joints[idx])
00143             exec('line_edit = self.%s' % name)
00144             line_edit.setText(str(deg))
00145 
00146     def _create_node(self, name=None):
00147         if name == None:
00148             nname = self.name + str(self.counter)
00149         else:
00150             nname = name
00151     
00152         #sstate = JointSequenceState(nname, str(self.arm_box.currentText()), self._read_joints_from_fields())
00153         sstate = JointSequenceState(nname, str(self.arm_box.currentText()), self.joint_angs_list)
00154         sstate.set_robot(self.rcommander.pr2)
00155         return sstate
00156 
00157     def _node_selected(self, my_node):
00158         self.joint_angs_list = my_node.joint_waypoints
00159         for d in self.joint_angs_list:
00160             self.list_widget.addItem(d['name'])
00161         self.arm_box.setCurrentIndex(self.arm_box.findText(my_node.arm))
00162         self.list_widget.setCurrentItem(self.list_widget.item(0))
00163 
00164     def reset(self):
00165         self.arm_box.setCurrentIndex(self.arm_box.findText('left'))
00166         for name in self.joint_name_fields:
00167             exec('self.%s.setText(str(0.))' % name)
00168 
00169     def get_smach_class(self):
00170         return JointSequenceState
00171 
00172 
00173 class JointSequenceState(smach.State, tu.StateBase): 
00174 
00175     TIME_OUT_FACTOR = 2.
00176 
00177     def __init__(self, name, arm, joint_waypoints):
00178         self.name = name
00179         tu.StateBase.__init__(self, self.name)
00180         self.arm = arm
00181         self.joint_waypoints = joint_waypoints
00182         self.arm_obj = None
00183         self.__init_unpicklables__()
00184 
00185     def execute(self, userdata):
00186         #Construct trajectory command
00187         times = []
00188         wps = []
00189         for d in self.joint_waypoints:
00190             wps.append(np.matrix(d['angs']).T)
00191             times.append(d['time'])
00192 
00193         self.arm_obj.set_poses(np.column_stack(wps), np.cumsum(np.array(times)), block=False)
00194         client = self.arm_obj.client
00195         state = client.get_state()
00196         print 'goal status', tu.goal_status_to_string(state)
00197 
00198         #Monitor execution
00199         trajectory_time_out = JointSequenceState.TIME_OUT_FACTOR * np.sum(times)
00200         succeeded = False
00201         preempted = False
00202         r = rospy.Rate(30)
00203         start_time = rospy.get_time()
00204         while True:
00205             #we have been preempted
00206             if self.preempt_requested():
00207                 rospy.loginfo('JointSequenceState: preempt requested')
00208                 client.cancel_goal()
00209                 self.service_preempt()
00210                 preempted = True
00211                 break
00212 
00213             if (rospy.get_time() - start_time) > trajectory_time_out:
00214                 client.cancel_goal()
00215                 rospy.loginfo('JointSequenceState: timed out!')
00216                 succeeded = True
00217                 break
00218 
00219             #print tu.goal_status_to_string(state)
00220             if (state not in [am.GoalStatus.ACTIVE, am.GoalStatus.PENDING]):
00221                 if state == am.GoalStatus.SUCCEEDED:
00222                     rospy.loginfo('JointSequenceState: Succeeded!')
00223                     succeeded = True
00224                 break
00225 
00226             r.sleep()
00227 
00228         if preempted:
00229             return 'preempted'
00230 
00231         if succeeded:
00232             return 'succeeded'
00233 
00234         return 'failed'
00235 
00236     def set_robot(self, pr2):
00237         if self.arm == 'left':
00238             self.arm_obj = pr2.left
00239 
00240         if self.arm == 'right':
00241             self.arm_obj = pr2.right
00242 
00243     def __init_unpicklables__(self):
00244         smach.State.__init__(self, outcomes = ['succeeded', 'preempted', 'failed'], input_keys = [], output_keys = [])
00245 
00246     def __getstate__(self):
00247         state = tu.StateBase.__getstate__(self)
00248         my_state = [self.name, self.arm, self.joint_waypoints] 
00249         return {'state_base': state, 'self': my_state}
00250 
00251     def __setstate__(self, state):
00252         tu.StateBase.__setstate__(self, state['state_base'])
00253         self.name, self.arm, self.joint_waypoints = state['self']
00254         self.__init_unpicklables__()
00255 
00256 


rcommander
Author(s): Hai Nguyen (haidai@gmail.com)
autogenerated on Thu Nov 28 2013 11:46:34