Go to the documentation of this file.00001
00002 import rospy
00003 from PyQt4.QtGui import *
00004 from PyQt4.QtCore import *
00005 import tool_utils as tu
00006 import smach
00007 import os.path as pt
00008 import graph_model as gm
00009
00010
00011 class StateMachineTool(tu.ToolBase):
00012
00013 def __init__(self, rcommander):
00014 tu.ToolBase.__init__(self, rcommander, 'state_machine', 'State Machine', StateMachineNode)
00015 self.child_gm = None
00016
00017 def fill_property_box(self, pbox):
00018 formlayout = pbox.layout()
00019 self.filename_edit = QLineEdit(pbox)
00020 self.filename_edit.setText("...")
00021 self.open_file_button = QPushButton(pbox)
00022 self.open_file_button.setText('Select...')
00023 self.rcommander.connect(self.open_file_button, SIGNAL('clicked()'), self.open_file_cb)
00024
00025 formlayout.addRow('&Filename', self.filename_edit)
00026 formlayout.addRow(self.open_file_button)
00027
00028 def open_file_cb(self):
00029 dialog = QFileDialog(self.rcommander, 'Open State Machine', '~')
00030 dialog.setFileMode(QFileDialog.Directory)
00031 dialog.setViewMode(QFileDialog.List)
00032
00033
00034 import rospy.core as rpc
00035 rpc._shutdown_flag = False
00036
00037 if dialog.exec_():
00038 filenames = dialog.selectedFiles()
00039 filename = str(filenames[0])
00040 self.filename_edit.setText(filename)
00041
00042 def new_node(self, name=None):
00043 child_gm = self.child_gm
00044 self.child_gm = None
00045
00046 if (child_gm == None) and (str(self.filename_edit.text()) != '...'):
00047
00048 print 'state machine tool loading', self.filename_edit.text()
00049 child_gm = gm.GraphModel.load(str(self.filename_edit.text()))
00050
00051 curr_document = gm.FSMDocument(name, modified=True, real_filename=False)
00052 child_gm.set_document(curr_document)
00053 else:
00054 if child_gm != None:
00055 curr_document = gm.FSMDocument(name, modified=True, real_filename=False)
00056 child_gm.set_document(curr_document)
00057 return StateMachineNode(name, child_gm)
00058 if name == None:
00059 nname = self.name + str(self.counter)
00060 return StateMachineNode(nname, None)
00061 else:
00062
00063 return None
00064
00065 return StateMachineNode(name, child_gm)
00066
00067 def set_node_properties(self, my_node):
00068 self.child_gm = my_node.child_gm
00069 if self.child_gm == None:
00070 return
00071 if self.child_gm.get_document() != None:
00072 fname = self.child_gm.get_document().get_filename()
00073 if fname != None:
00074 self.filename_edit.setText(fname)
00075
00076 def reset(self):
00077 self.filename_edit.setText("...")
00078 self.child_gm = None
00079
00080
00081 class StateMachineNode(tu.EmbeddableState):
00082
00083 def __init__(self, name, child_gm):
00084 tu.EmbeddableState.__init__(self, name, child_gm)
00085
00086 def get_smach_state(self):
00087 return StateMachineNodeSmach(self.child_gm)
00088
00089 def recreate(self, graph_model):
00090
00091 return StateMachineNode(self.get_name(), graph_model)
00092
00093 class StateMachineNodeSmach(smach.State):
00094
00095 def __init__(self, child_gm):
00096 self.child_gm = child_gm
00097
00098 def set_robot(self, robot):
00099 self.robot = robot
00100 input_keys = []
00101 output_keys = []
00102 outcomes = []
00103 if self.child_gm != None:
00104 sm = self.child_gm.create_state_machine(robot)
00105 input_keys = list(sm.get_registered_input_keys())
00106 output_keys = list(sm.get_registered_output_keys())
00107 outcomes = list(sm.get_registered_outcomes()) + ['preempted']
00108 smach.State.__init__(self, outcomes = outcomes, input_keys = input_keys, output_keys = output_keys)
00109
00110
00111 def execute(self, userdata):
00112 child_gm = self.child_gm
00113 sm = child_gm.create_state_machine(self.robot, userdata=userdata._ud)
00114 child_gm.run(self.child_gm.get_start_state(), state_machine=sm)
00115 rthread = child_gm.sm_thread['run_sm']
00116
00117 preempted = False
00118 r = rospy.Rate(30)
00119 while True:
00120 if rthread.exception != None:
00121 raise rthread.exception
00122
00123 if rthread.outcome != None:
00124 rospy.loginfo('State Machine Node: child node finished with outcome ' + rthread.outcome)
00125 break
00126
00127 if not rthread.isAlive():
00128 rospy.loginfo('State Machine Node: child node died')
00129 break
00130
00131 if self.preempt_requested():
00132 rospy.loginfo('State Machine Node: preempt requested')
00133 rthread.preempt()
00134 self.service_preempt()
00135 preempted = True
00136 break
00137
00138 r.sleep()
00139
00140
00141 if preempted:
00142 return 'preempted'
00143 else:
00144 return rthread.outcome
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215