00001
00002
00003 import roslib
00004 roslib.load_manifest('openrtm_tools')
00005
00006 import sys
00007 import os
00008 import time
00009 import optparse
00010
00011 from xml.dom.minidom import parse
00012
00013 import rtctree
00014 from rtshell import rtcon
00015 from rtshell import path
00016 from rtshell import state_control_base
00017 from rtshell import rts_exceptions
00018
00019 def alive_component(path):
00020 tree=rtctree.tree.RTCTree()
00021 if tree.has_path(path) and tree.is_component(path):
00022 node = tree.get_node(path)
00023 return node.plain_state_string
00024 else:
00025 return False
00026
00027 def wait_component(cmd_path):
00028 count=0
00029 path = rtctree.path.parse_path(cmd_path)[0]
00030 node = alive_component(path)
00031 while not node and count < 30:
00032 node = alive_component(path)
00033 print >>sys.stderr, "\033[33m[rtmlaunch] Wait for ",cmd_path," ",count,"/30\033[0m"
00034 count += 1
00035 time.sleep(1)
00036 if not node:
00037 raise rts_exceptions.NoSuchObjectError(cmd_path)
00038 return node
00039
00040 def check_connect(src_path, dest_path):
00041 tree=rtctree.tree.RTCTree()
00042 src_path, src_port = rtctree.path.parse_path(src_path)
00043 dest_path, dest_port = rtctree.path.parse_path(dest_path)
00044 src_node = tree.get_node(src_path)
00045 dest_node = tree.get_node(dest_path)
00046 port = src_node.get_port_by_name(src_port)
00047 for conn in port.connections:
00048 for name, p in conn.ports:
00049 tmp_dest_path, tmp_dest_port = rtctree.path.parse_path(name)
00050 if dest_path[-1] == tmp_dest_path[-1] and dest_port == tmp_dest_port:
00051 return True
00052 return False
00053
00054 def rtconnect(nameserver, tags):
00055 import re
00056 for tag in tags:
00057
00058
00059 exec_flag = True
00060 if tag.attributes.get(u'if'):
00061 val = tag.attributes.get(u'if').value
00062 arg = val.split(" ")[1].strip(")")
00063 exec_flag = get_flag_from_argv(arg)
00064 if tag.attributes.get(u'unless'):
00065 val = tag.attributes.get(u'unless').value
00066 arg = val.split(" ")[1].strip(")")
00067 exec_flag = not get_flag_from_argv(arg)
00068 if not exec_flag:
00069 continue
00070
00071 source_path = nameserver+"/"+tag.attributes.get("from").value
00072 dest_path = nameserver+"/"+tag.attributes.get("to").value
00073 source_path = re.sub("\$\(arg SIMULATOR_NAME\)",simulator,source_path);
00074 dest_path = re.sub("\$\(arg SIMULATOR_NAME\)",simulator,dest_path);
00075
00076 source_full_path = path.cmd_path_to_full_path(source_path)
00077 dest_full_path = path.cmd_path_to_full_path(dest_path)
00078 if tag.attributes.get("subscription_type") != None:
00079 sub_type = tag.attributes.get("subscription_type").value
00080 if not sub_type in ['flush','new','periodic']:
00081 print >>sys.stderr, sub_type+' is not a subscription type'
00082 continue
00083 else:
00084 sub_type = 'flush'
00085 if sub_type == 'new':
00086 push_policy = 'all'
00087
00088 try:
00089 wait_component(source_full_path)
00090 wait_component(dest_full_path)
00091 if check_connect(source_full_path,dest_full_path):
00092 continue
00093 except Exception, e:
00094 print >>sys.stderr, '\033[31m[rtmlaunch] [ERROR] Could not Connect (', source_full_path, ',', dest_full_path, '): ', e,'\033[0m'
00095 return 1
00096
00097 try:
00098 sub_type = str(sub_type)
00099 props = {'dataport.subscription_type': sub_type}
00100 if sub_type == 'new':
00101 props['dataport.publisher.push_policy'] = 'all'
00102 elif sub_type == 'periodic':
00103 props['dataport.publisher.push_policy'] = 'all'
00104 if tag.attributes.get("push_rate") != None:
00105 props['dataport.push_rate'] = str(tag.attributes.get("push_rate").value)
00106 else:
00107 props['dataport.push_rate'] = str('50.0')
00108 options = optparse.Values({'verbose': False, 'id': '', 'name': None, 'properties': props})
00109 print >>sys.stderr, "[rtmlaunch] Connected from",source_path
00110 print >>sys.stderr, "[rtmlaunch] to",dest_path
00111 print >>sys.stderr, "[rtmlaunch] with",options
00112 try :
00113 rtcon.connect_ports(source_path, source_full_path, dest_path, dest_full_path, options, tree=None)
00114 except Exception, e_1_1_0:
00115 try:
00116 rtcon.connect_ports([(source_path,source_full_path), (dest_path, dest_full_path)], options, tree=None)
00117 except Exception, e_1_0_0:
00118 print >>sys.stderr, '\033[31m[rtmlaunch] {0} did not work on both OpenRTM 1.0.0 and 1.1.0'.format(os.path.basename(sys.argv[1])),'\033[0m'
00119 print >>sys.stderr, '\033[31m[rtmlaunch] OpenRTM 1.0.0 {0}'.format(e_1_0_0),'\033[0m'
00120 print >>sys.stderr, '\033[31m[rtmlaunch] OpenRTM 1.1.0 {0}'.format(e_1_1_0),'\033[0m'
00121 print >>sys.stderr, '\033[31m[rtmlaunch] This is very weird situation, Please check your network\033[0m'
00122 print >>sys.stderr, '\033[31m[rtmlaunch] configuration with `ifconfig` on both robot and client side. \033[0m'
00123 print >>sys.stderr, '\033[31m[rtmlaunch] Having multiple network interface sometimes causes problem, \033[0m'
00124 print >>sys.stderr, '\033[31m[rtmlaunch] please see FAQ site http://www.openrtm.org/OpenRTM-aist/html/FAQ2FE38388E383A9E38396E383ABE382B7E383A5E383BCE38386E382A3E383B3E382B0.html#f2bc375d\033[0m'
00125 print >>sys.stderr, '\033[31m[rtmlaunch] Issue related to this https://github.com/start-jsk/rtmros_hironx/issues/33\033[0m'
00126 print >>sys.stderr, '\033[31m[rtmlaunch] ~/.ros/log may contains usefully informations\033[0m'
00127 except Exception, e:
00128 print >>sys.stderr, '\033[31m[rtmlaunch] {0}: {1}'.format(os.path.basename(sys.argv[1]), e),'\033[0m'
00129 return 0
00130
00131 def rtactivate(nameserver, tags):
00132 def activate_action(object, ec_index):
00133 object.activate_in_ec(ec_index)
00134 for tag in tags:
00135
00136
00137 exec_flag = True
00138 if tag.attributes.get(u'if'):
00139 val = tag.attributes.get(u'if').value
00140 arg = val.split(" ")[1].strip(")")
00141 exec_flag = get_flag_from_argv(arg)
00142 if tag.attributes.get(u'unless'):
00143 val = tag.attributes.get(u'unless').value
00144 arg = val.split(" ")[1].strip(")")
00145 exec_flag = not get_flag_from_argv(arg)
00146 if not exec_flag:
00147 continue
00148
00149 cmd_path = nameserver+"/"+tag.attributes.get("component").value
00150 full_path = path.cmd_path_to_full_path(cmd_path)
00151
00152 try:
00153 state = wait_component(full_path)
00154 if state == 'Active':
00155 continue
00156 else:
00157 print >>sys.stderr, "[rtmlaunch] Activate <-",state,full_path
00158 except Exception, e:
00159 print >>sys.stderr, '\033[31m[rtmlaunch] Could not Activate (', cmd_path, ') : ', e,'\033[0m'
00160 return 1
00161 try:
00162 options = optparse.Values({"ec_index": 0, 'verbose': False})
00163 try :
00164 state_control_base.alter_component_state(activate_action, cmd_path, full_path, options, None)
00165 except Exception, e:
00166 state_control_base.alter_component_states(activate_action, [(cmd_path, full_path)], options, None)
00167 except Exception, e:
00168 print >>sys.stderr, '[rtmlaunch] {0}: {1}'.format(os.path.basename(sys.argv[0]), e)
00169 return 1
00170 return 0
00171
00172 def main():
00173 global simulator
00174 usage = '''Usage: %prog [launchfile]'''
00175 if len(sys.argv) <= 1:
00176 print >>sys.stderr, usage
00177 return 1
00178 fullpathname = sys.argv[1]
00179 print >>sys.stderr, "[rtmlaunch] starting... ",fullpathname
00180 try:
00181 parser = parse(fullpathname)
00182 nodes = parser.getElementsByTagName("launch")[0].childNodes
00183 remove_nodes = []
00184 for node in nodes:
00185 if node.nodeName == u'group':
00186 if node.attributes.get(u'if'):
00187 val = node.getAttributeNode(u'if').value
00188 arg = val.split(" ")[1].strip(")")
00189 if not get_flag_from_argv(arg):
00190 remove_nodes.append(node)
00191 if node.attributes.get(u'unless'):
00192 val = node.getAttributeNode(u'unless').value
00193 arg = val.split(" ")[1].strip(")")
00194 if get_flag_from_argv(arg):
00195 remove_nodes.append(node)
00196
00197 for remove_node in remove_nodes:
00198 nodes.remove(remove_node)
00199 except Exception,e:
00200 print e
00201 return 1
00202
00203 if os.getenv("RTCTREE_NAMESERVERS") == None:
00204 print >>sys.stderr, "[rtmlaunch] RTCTREE_NAMESERVERS is not set, use localhost:15005"
00205 nameserver = "localhost:15005"
00206 os.environ["RTCTREE_NAMESERVERS"] = nameserver
00207 else:
00208 nameserver = os.getenv("RTCTREE_NAMESERVERS")
00209
00210 simulator = os.getenv("SIMULATOR_NAME","Simulator")
00211 print >>sys.stderr, "[rtmlaunch] RTCTREE_NAMESERVERS", nameserver, os.getenv("RTCTREE_NAMESERVERS")
00212 print >>sys.stderr, "[rtmlaunch] SIMULATOR_NAME", simulator
00213 while 1:
00214 print >>sys.stderr, "[rtmlaunch] check connection/activation"
00215 rtconnect(nameserver, parser.getElementsByTagName("rtconnect"))
00216 rtactivate(nameserver, parser.getElementsByTagName("rtactivate"))
00217 time.sleep(10)
00218
00219 def get_flag_from_argv(arg):
00220 for a in sys.argv:
00221 if arg in a:
00222 return True if 'true' in a.split("=")[1] else False
00223
00224 import signal
00225 def signal_handler(signum, frame):
00226 sigdict = dict((k, v) for v, k in signal.__dict__.iteritems() if v.startswith('SIG'))
00227 print >>sys.stderr, "\033[33m[rtmlaunch] Catch signal %r, exitting...\033[0m"%(sigdict[signum])
00228 sys.exit(0)
00229
00230 if __name__ == '__main__':
00231 signal.signal(signal.SIGINT, signal_handler)
00232 main()
00233
00234
00235
00236