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


rcommander_pr2_gui
Author(s): Hai Nguyen
autogenerated on Thu Dec 12 2013 12:09:58