gripper_event_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 pr2_gripper_sensor_msgs.msg as gr
00006 import actionlib_msgs.msg as am
00007 import actionlib
00008 import tool_utils as tu
00009 import smach
00010 import graph_model as gm
00011 import sm_thread_runner as smtr
00012 
00013 class GripperEventTool(tu.ToolBase):
00014 
00015     def __init__(self, rcommander):
00016         tu.ToolBase.__init__(self, rcommander, 'gripper_event', 'Gripper Event')
00017         self.child_gm = None
00018 
00019     #NEED TO IMPLEMENT
00020     def get_smach_class(self):
00021         return GripperEventState
00022 
00023     #NEED TO IMPLEMENT
00024     def set_child_node(self, child_smach):
00025         self.child_gm = gm.GraphModel()
00026         self.child_gm.add_node(child_smach)
00027         self.child_gm.set_start_state(child_smach.get_name())
00028         self.child_gm.set_document(gm.FSMDocument(child_smach.get_name(), modified=False, real_filename=False))
00029 
00030     def fill_property_box(self, pbox):
00031         formlayout = pbox.layout()
00032 
00033         self.gripper_radio_boxes, self.gripper_radio_buttons = tu.make_radio_box(pbox, ['Left', 'Right'], 'gripper_event_arm')
00034         self.event_box = QComboBox(pbox)
00035         for event in GripperEventState.EVENT_LIST:
00036             self.event_box.addItem(event)
00037         self.accel_box = tu.SliderBox(pbox, 8.25, 30, 0., .25, 'gripper_accel', units='m/s^2')
00038         self.slip_box = tu.SliderBox(pbox, .01, -.5, .5, .1, 'gripper_slip', units='')
00039 
00040         formlayout.addRow('&Gripper', self.gripper_radio_boxes)
00041         formlayout.addRow('&Event', self.event_box)
00042         formlayout.addRow('&Acceleration', self.accel_box.container)
00043         formlayout.addRow('&Slip', self.slip_box.container)
00044         pbox.update()
00045 
00046     def _create_node(self, name=None):
00047         if self.child_gm == None:
00048             raise RuntimeError('No child node!')
00049         selected_arm = None
00050         for r in self.gripper_radio_buttons:
00051             if r.isChecked():
00052                 selected_arm = str(r.text()).lower()
00053         if selected_arm == None:
00054             raise RuntimeError('No arm selected!')
00055 
00056         event_type = str(self.event_box.currentText())
00057         accel_val = self.accel_box.value()
00058         slip_val = self.slip_box.value()
00059 
00060         if name == None:
00061             nname = self.name + str(self.counter)
00062         else:
00063             nname = name
00064 
00065         return GripperEventState(nname, self.child_gm, selected_arm, event_type, accel_val, slip_val)
00066     
00067     def _node_selected(self, gripper_event_state):
00068         if gripper_event_state.arm == 'left':
00069             self.gripper_radio_buttons[0].setChecked(True)
00070         if gripper_event_state.arm == 'right':
00071             self.gripper_radio_buttons[1].setChecked(True)
00072 
00073         self.event_box.setCurrentIndex(self.event_box.findText(gripper_event_state.event_type))
00074         self.accel_box.set_value(gripper_event_state.accel)
00075         self.slip_box.set_value(gripper_event_state.slip)
00076         self.child_gm = gripper_event_state.child_gm
00077 
00078         #self.child_node = gripper_event_state.get_child()
00079 
00080     def reset(self):
00081         self.gripper_radio_buttons[0].setChecked(True)
00082         self.event_box.setCurrentIndex(self.event_box.findText(GripperEventState.EVENT_LIST[0]))
00083         self.accel_box.set_value(8.25)
00084         self.slip_box.set_value(.01)
00085         self.child_gm = None
00086 
00087 
00088 class GripperEventState(smach.State, tu.EmbeddableState): 
00089 
00090     EVENT_LIST = ['acceleration', 'slip', 'finger side impact or acceleration', 'slip and acceleration', 'finger side impact, slip or acceleration']
00091     EVENT_CODES = {'acceleration':                             gr.PR2GripperEventDetectorCommand.ACC,
00092                    'slip':                                     gr.PR2GripperEventDetectorCommand.SLIP,
00093                    'finger side impact or acceleration':       gr.PR2GripperEventDetectorCommand.FINGER_SIDE_IMPACT_OR_ACC,
00094                    'slip and acceleration':                    gr.PR2GripperEventDetectorCommand.SLIP_AND_ACC,
00095                    'finger side impact, slip or acceleration': gr.PR2GripperEventDetectorCommand.FINGER_SIDE_IMPACT_OR_SLIP_OR_ACC}
00096     EVENT_OUTCOME = 'detected_event'
00097 
00098     def __init__(self, name, child_gm, arm, event_type, accel, slip):
00099         tu.EmbeddableState.__init__(self, name, child_gm)
00100         self.arm = arm
00101         self.event_type = event_type
00102         self.accel = accel
00103         self.slip = slip
00104         self.__init_unpicklables__() 
00105 
00106     def __init_unpicklables__(self):
00107         #Init smach stuff
00108         input_keys = []
00109         output_keys = []
00110         outcomes = []
00111 
00112         if self.get_child() != None:
00113             sm = self.get_child().create_state_machine()
00114             input_keys = list(sm.get_registered_input_keys())
00115             output_keys = list(sm.get_registered_output_keys())
00116             outcomes = list(sm.get_registered_outcomes()) + [GripperEventState.EVENT_OUTCOME]
00117         smach.State.__init__(self, outcomes = outcomes, input_keys = input_keys, output_keys = output_keys)
00118 
00119         #Setup our action server
00120         if self.arm == 'left':
00121             a = 'l'
00122         elif self.arm == 'right':
00123             a = 'r'
00124         else:
00125             raise RuntimeError('Error')
00126         evd_name = a + '_gripper_sensor_controller/event_detector'
00127         self.action_client = actionlib.SimpleActionClient(evd_name, gr.PR2GripperEventDetectorAction)
00128 
00129     #Can't pickle graph models, have to have other mechanisms saving it
00130     def __getstate__(self):
00131         state = tu.EmbeddableState.__getstate__(self)
00132         my_state = [self.arm, self.event_type, self.accel, self.slip]
00133         return {'embeddable': state, 'self': my_state}
00134 
00135     #Can't pickle graph models, have to have other mechanisms saving it
00136     def __setstate__(self, state):
00137         tu.EmbeddableState.__setstate__(self, state['embeddable'])
00138         self.arm, self.event_type, self.accel, self.slip = state['self']
00139         self.__init_unpicklables__()
00140 
00141     #must implement in embeddable nodes
00142     def recreate(self, new_graph_model):
00143         return GripperEventState(self.name, new_graph_model, self.arm, self.event_type, self.accel, self.slip)
00144 
00145     def _detected_event(self):
00146         state = self.action_client.get_state()
00147         gripper_event_detected = state not in [am.GoalStatus.ACTIVE, am.GoalStatus.PENDING]
00148         return gripper_event_detected
00149 
00150     def execute(self, userdata):
00151         print '>> executing, got userdata:', userdata, 'keys', userdata.keys()
00152         print 'input keys', self.get_registered_input_keys(), 'ud_keys', userdata._ud.keys()
00153         rospy.sleep(2)
00154 
00155         goal = gr.PR2GripperEventDetectorGoal()
00156         goal.command.acceleration_trigger_magnitude = self.accel
00157         goal.command.slip_trigger_magnitude = self.slip
00158         goal.command.trigger_conditions = GripperEventState.EVENT_CODES[self.event_type]
00159         #print 'ge: sending goal'
00160         self.action_client.send_goal(goal)
00161 
00162         #Let state machine execute, but kill its thread if we detect an event
00163         #print 'ge: creating sm and running'
00164         child_gm = self.get_child()
00165         #self.child = child_gm
00166 
00167         #print dir(userdata)
00168         sm = child_gm.create_state_machine(userdata=userdata._ud)
00169         #child_gm.run(self.child_smach_node.get_name(), state_machine=sm)
00170         child_gm.run(self.child_gm.get_start_state(), state_machine=sm)
00171         rthread = child_gm.sm_thread['run_sm']
00172 
00173         #rthread = smtr.ThreadRunSM(self.child_smach_node.get_name(), sm)
00174         #rthread.start()
00175 
00176         
00177         event = self._detected_event()
00178         preempted = False
00179         r = rospy.Rate(100)
00180         while not event:
00181             if rthread.exception != None:
00182                 raise rthread.exception
00183 
00184             if rthread.outcome != None:
00185                 rospy.loginfo('Gripper Event Tool: child node finished with outcome ' + rthread.outcome)
00186                 break
00187 
00188             if not rthread.isAlive():
00189                 rospy.loginfo('Gripper Event Tool: child node died')
00190                 break
00191 
00192             if self.preempt_requested():
00193                 rospy.loginfo('Gripper Event Tool: preempt requested')
00194                 self.service_preempt()
00195                 preempted = True
00196                 break
00197 
00198             event = self._detected_event() 
00199             if event:
00200                 rospy.loginfo('Gripper Event Tool: DETECTED EVENT')
00201 
00202             r.sleep()
00203 
00204         #print 'ge: sm finished'
00205 
00206         #send preempt to whatever is executing
00207         rthread.preempt()
00208         rthread.except_preempt()
00209         #self.child_gm = None
00210         child_gm.sm_thread = {} #Reset sm thread dict
00211 
00212         if preempted:
00213             return 'preempted'
00214 
00215         if event:
00216             return self.EVENT_OUTCOME
00217         else:
00218             #reverse look up child outcome
00219             #for outcome, outcome_rename in child_gm.current_children_of(self.child_smach_node.name):
00220             #TODO look at this
00221             #for outcome, outcome_rename in child_gm.current_children_of(self.get_child_name()):
00222             #    if outcome_rename == rthread.outcome:
00223             #        return outcome
00224             #if not found just return what we have
00225             return rthread.outcome
00226 
00227 
00228 
00229 
00230 
00231 
00232 #from pr2_gripper_sensor_msgs.msg import PR2GripperFindContactAction, PR2GripperFindContactGoal, \
00233 #    PR2GripperGrabAction, PR2GripperGrabGoal, PR2GripperEventDetectorAction, PR2GripperEventDetectorGoal
00234 
00235 #whicharm = 'r'
00236 #evd_client = actionlib.SimpleActionClient(evd_name, gr.PR2GripperEventDetectorAction)
00237 #
00238 #goal = PR2GripperEventDetectorGoal()
00239 #goal.command.acceleration_trigger_magnitude = accel
00240 #goal.command.slip_trigger_magnitude = slip
00241 #goal.command.trigger_conditions = goal.command.ACC
00242 #goal.command.trigger_conditions = goal.command.SLIP
00243 #goal.command.trigger_conditions = goal.command.FINGER_SIDE_IMPACT_OR_ACC
00244 #goal.command.trigger_conditions = goal.command.SLIP_AND_ACC
00245 #goal.command.trigger_conditions = goal.command.FINGER_SIDE_IMPACT_OR_SLIP_OR_ACC 
00246 
00247 #Either detect event or not
00248 #evd_client.send_goal(goal)
00249 #evd_client.wait_for_result()
00250 #state = evd_client.get_state()
00251 #if state == am.GoalStatus.SUCCEEDED:
00252 


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