00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 import types
00062
00063
00064 import roslib
00065 roslib.load_manifest('cob_script_server')
00066 import rospy
00067
00068
00069
00070
00071 import pygraphviz as pgv
00072
00073 graph=""
00074 graph_wait_list=[]
00075 function_counter = 0
00076 ah_counter = 0
00077 graph = pgv.AGraph()
00078 graph.node_attr['shape']='box'
00079 last_node = "Start"
00080
00081
00082
00083
00084
00085 class action_handle:
00086
00087 def __init__(self, function_name, component_name, parameter_name, blocking, parse):
00088 self.parent_node = ""
00089 self.error_code = -1
00090 self.wait_log = False
00091 self.function_name = function_name
00092 self.component_name = component_name
00093 self.parameter_name = parameter_name
00094 self.state = ScriptState.UNKNOWN
00095 self.blocking = blocking
00096 self.parse = parse
00097 self.level = int(rospy.get_param("/script_server/level",100))
00098 self.state_pub = rospy.Publisher("/script_server/state", ScriptState)
00099 self.AppendNode(blocking)
00100
00101
00102 def set_graph(self,graph):
00103 rospy.set_param("/script_server/graph", graph.string())
00104
00105
00106 def get_graph(self):
00107
00108 if rospy.has_param('script_server/graph'):
00109 dotcode = rospy.get_param("script_server/graph")
00110 graph=pgv.AGraph(dotcode)
00111 else:
00112 graph=pgv.AGraph()
00113 graph.add_node('no graph available')
00114 return graph
00115
00116
00117 def set_client(self,client):
00118 self.client = client
00119
00120
00121 def set_active(self):
00122 self.check_pause()
00123 self.state = ScriptState.ACTIVE
00124 self.error_code = -1
00125 self.PublishState()
00126
00127 global ah_counter
00128 ah_counter += 1
00129
00130
00131 def check_pause(self):
00132 param_string = "/script_server/pause"
00133 while bool(rospy.get_param(param_string,False)):
00134 rospy.logwarn("Script is paused...")
00135 self.state = ScriptState.PAUSED
00136 self.PublishState()
00137 rospy.sleep(1)
00138 if self.state == ScriptState.PAUSED:
00139 rospy.loginfo("...continuing script")
00140
00141
00142 def set_succeeded(self):
00143 self.state = ScriptState.SUCCEEDED
00144 self.error_code = 0
00145 self.PublishState()
00146
00147 global ah_counter
00148 ah_counter -= 1
00149
00150
00151 def set_failed(self,error_code):
00152 self.state = ScriptState.FAILED
00153 self.error_code = error_code
00154 self.PublishState()
00155
00156 global ah_counter
00157 ah_counter -= 1
00158
00159
00160 def get_state(self):
00161 return self.state
00162
00163
00164 def get_error_code(self):
00165 return self.error_code
00166
00167
00168 def GetGraphstring(self):
00169 global function_counter
00170 if type(self.parameter_name) is types.StringType:
00171 graphstring = str(function_counter)+"_"+self.function_name+"_"+self.component_name+"_"+self.parameter_name
00172 else:
00173 graphstring = str(function_counter)+"_"+self.function_name+"_"+self.component_name
00174 return graphstring
00175
00176
00177 def GetLevel(self,function_name):
00178 if (function_name == "move"):
00179 level = 0
00180 elif (function_name == "init"):
00181 level = 1
00182 elif (function_name == "stop"):
00183 level = 1
00184 elif (function_name == "sleep"):
00185 level = 2
00186 else:
00187 level = 100
00188 return level
00189
00190
00191 def AppendNode(self, blocking=True):
00192 global graph
00193 global last_node
00194 global graph_wait_list
00195 global function_counter
00196 graphstring = self.GetGraphstring()
00197 if self.parse:
00198 if ( self.level >= self.GetLevel(self.function_name)):
00199
00200 graph.add_edge(last_node, graphstring)
00201 for waiter in graph_wait_list:
00202 graph.add_edge(waiter, graphstring)
00203 self.graph_wait_list=[]
00204 if blocking:
00205 self.last_node = graphstring
00206 else:
00207 self.parent_node = graphstring
00208
00209
00210
00211
00212 function_counter += 1
00213
00214
00215 def PublishState(self):
00216 script_state = ScriptState()
00217 script_state.header.stamp = rospy.Time.now()
00218 script_state.number = self.function_counter
00219 script_state.function_name = self.function_name
00220 script_state.component_name = self.component_name
00221 script_state.full_graph_name = self.GetGraphstring()
00222 if ( type(self.parameter_name) is str ):
00223 script_state.parameter_name = self.parameter_name
00224 else:
00225 script_state.parameter_name = ""
00226 script_state.state = self.state
00227 script_state.error_code = self.error_code
00228 self.state_pub.publish(script_state)
00229
00230
00231
00232
00233
00234
00235 def wait(self, duration=None):
00236 global ah_counter
00237 ah_counter += 1
00238 self.blocking = True
00239 self.wait_for_finished(duration,True)
00240
00241
00242
00243
00244
00245
00246 def wait_inside(self, duration=None):
00247 if self.blocking:
00248 self.wait_for_finished(duration,True)
00249 else:
00250 thread.start_new_thread(self.wait_for_finished,(duration,False,))
00251 return self.error_code
00252
00253
00254
00255
00256
00257
00258
00259 def wait_for_finished(self, duration, logging):
00260 global graph_wait_list
00261 if(self.parse):
00262 if(self.parent_node != ""):
00263 self.graph_wait_list.append(self.parent_node)
00264 return
00265
00266 if self.error_code <= 0:
00267 if duration is None:
00268 if logging:
00269 rospy.loginfo("Wait for <<%s>> reaching <<%s>>...",self.component_name, self.parameter_name)
00270 self.client.wait_for_result()
00271 else:
00272 if logging:
00273 rospy.loginfo("Wait for <<%s>> reached <<%s>> (max %f secs)...",self.component_name, self.parameter_name,duration)
00274 if not self.client.wait_for_result(rospy.Duration(duration)):
00275 if logging:
00276 rospy.logerr("Timeout while waiting for <<%s>> to reach <<%s>>. Continuing...",self.component_name, self.parameter_name)
00277 self.error_code = 10
00278 return
00279 if logging:
00280 rospy.loginfo("...<<%s>> reached <<%s>>",self.component_name, self.parameter_name)
00281 else:
00282 rospy.logwarn("Execution of <<%s>> to <<%s>> was aborted, wait not possible. Continuing...",self.component_name, self.parameter_name)
00283 self.set_failed(self.error_code)
00284 return
00285
00286 self.set_succeeded()