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 import socket
00011
00012 from xml.dom.minidom import parse
00013
00014 import rtctree
00015 from rtshell import rtcon
00016 from rtshell import path
00017 from rtshell import state_control_base
00018 from rtshell import rts_exceptions
00019
00020 def alive_component(path, tree):
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 tree._root._remove_all_children()
00026 tree.load_servers_from_env()
00027 return False
00028
00029 def wait_component(cmd_path, tree):
00030 count=0
00031 path = rtctree.path.parse_path(cmd_path)[0]
00032 node = alive_component(path, tree)
00033 if not node:
00034 while count < 30:
00035 print >>sys.stderr, "\033[33m[rtmlaunch] Wait for ",cmd_path," ",count,"/30\033[0m"
00036 node = alive_component(path, tree)
00037 if node:
00038 return node
00039 count += 1
00040 time.sleep(1)
00041 raise rts_exceptions.NoSuchObjectError(cmd_path)
00042 return node
00043
00044 def check_connect(src_path, dest_path, tree):
00045 src_path, src_port = rtctree.path.parse_path(src_path)
00046 dest_path, dest_port = rtctree.path.parse_path(dest_path)
00047 src_node = tree.get_node(src_path)
00048 dest_node = tree.get_node(dest_path)
00049 port = src_node.get_port_by_name(src_port)
00050 for conn in port.connections:
00051 for name, p in conn.ports:
00052 tmp_dest_path, tmp_dest_port = rtctree.path.parse_path(name)
00053 if dest_path[-1] == tmp_dest_path[-1] and dest_port == tmp_dest_port:
00054 return True
00055 return False
00056
00057 def replace_arg_tag_by_env (input_path):
00058 import re
00059 ret_str = input_path
00060 if len(input_path.split("$(arg")) > 1:
00061 arg_str = input_path.split("$(arg")[1].split(")")[0]
00062 env_str = os.getenv(arg_str.replace(" ", ""))
00063 if env_str != None:
00064
00065 ret_str = re.sub("\$\(arg"+arg_str+"\)",env_str,input_path)
00066 return ret_str
00067
00068 def rtconnect(nameserver, tags, tree):
00069 for tag in tags:
00070
00071
00072 exec_flag = True
00073 if tag.attributes.get(u'if'):
00074 val = tag.attributes.get(u'if').value
00075 arg = val.split(" ")[1].strip(")")
00076 exec_flag = get_flag_from_argv(arg)
00077 if tag.attributes.get(u'unless'):
00078 val = tag.attributes.get(u'unless').value
00079 arg = val.split(" ")[1].strip(")")
00080 exec_flag = not get_flag_from_argv(arg)
00081 if not exec_flag:
00082 continue
00083
00084 source_path = nameserver+"/"+tag.attributes.get("from").value
00085 dest_path = nameserver+"/"+tag.attributes.get("to").value
00086 source_path = replace_arg_tag_by_env(source_path)
00087 dest_path = replace_arg_tag_by_env(dest_path)
00088
00089 source_full_path = path.cmd_path_to_full_path(source_path)
00090 dest_full_path = path.cmd_path_to_full_path(dest_path)
00091 if tag.attributes.get("subscription_type") != None:
00092 sub_type = tag.attributes.get("subscription_type").value
00093 sub_type = replace_arg_tag_by_env(sub_type);
00094 if not sub_type in ['flush','new','periodic']:
00095 print >>sys.stderr, sub_type+' is not a subscription type'
00096 continue
00097 else:
00098 sub_type = 'flush'
00099 if sub_type == 'new':
00100 push_policy = 'all'
00101
00102 try:
00103 wait_component(source_full_path, tree)
00104 wait_component(dest_full_path, tree)
00105 if check_connect(source_full_path,dest_full_path, tree):
00106 continue
00107 except Exception, e:
00108 print >>sys.stderr, '\033[31m[rtmlaunch] [ERROR] Could not Connect (', source_full_path, ',', dest_full_path, '): ', e,'\033[0m'
00109 return 1
00110
00111 try:
00112 sub_type = str(sub_type)
00113 props = {'dataport.subscription_type': sub_type}
00114 if tag.attributes.get("push_policy") != None:
00115 push_policy = replace_arg_tag_by_env(str(tag.attributes.get("push_policy").value));
00116 else:
00117 push_policy = 'all'
00118 if sub_type == 'new':
00119 props['dataport.publisher.push_policy'] = push_policy
00120 elif sub_type == 'periodic':
00121 props['dataport.publisher.push_policy'] = push_policy
00122 if tag.attributes.get("push_rate") != None:
00123 props['dataport.push_rate'] = replace_arg_tag_by_env(str(tag.attributes.get("push_rate").value))
00124 else:
00125 props['dataport.push_rate'] = str('50.0')
00126 if tag.attributes.get("buffer_length") != None:
00127 props['dataport.buffer.length'] = replace_arg_tag_by_env(str(tag.attributes.get("buffer_length").value))
00128 options = optparse.Values({'verbose': False, 'id': '', 'name': None, 'properties': props})
00129 print >>sys.stderr, "[rtmlaunch] Connected from",source_path
00130 print >>sys.stderr, "[rtmlaunch] to",dest_path
00131 print >>sys.stderr, "[rtmlaunch] with",options
00132 try :
00133 rtcon.connect_ports(source_path, source_full_path, dest_path, dest_full_path, options, tree=tree)
00134 except Exception, e_1_1_0:
00135 try:
00136 rtcon.connect_ports([(source_path,source_full_path), (dest_path, dest_full_path)], options, tree=tree)
00137 except Exception, e_1_0_0:
00138 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'
00139 print >>sys.stderr, '\033[31m[rtmlaunch] OpenRTM 1.0.0 {0}'.format(e_1_0_0),'\033[0m'
00140 print >>sys.stderr, '\033[31m[rtmlaunch] OpenRTM 1.1.0 {0}'.format(e_1_1_0),'\033[0m'
00141 print >>sys.stderr, '\033[31m[rtmlaunch] This is very weird situation, Please check your network\033[0m'
00142 print >>sys.stderr, '\033[31m[rtmlaunch] configuration with `ifconfig` on both robot and client side. \033[0m'
00143 print >>sys.stderr, '\033[31m[rtmlaunch] Having multiple network interface sometimes causes problem, \033[0m'
00144 print >>sys.stderr, '\033[31m[rtmlaunch] please see FAQ site http://www.openrtm.org/OpenRTM-aist/html/FAQ2FE38388E383A9E38396E383ABE382B7E383A5E383BCE38386E382A3E383B3E382B0.html#f2bc375d\033[0m'
00145 print >>sys.stderr, '\033[31m[rtmlaunch] Issue related to this https://github.com/start-jsk/rtmros_hironx/issues/33\033[0m'
00146 print >>sys.stderr, '\033[31m[rtmlaunch] ~/.ros/log may contains usefully informations\033[0m'
00147 except Exception, e:
00148 print >>sys.stderr, '\033[31m[rtmlaunch] {0}: {1}'.format(os.path.basename(sys.argv[1]), e),'\033[0m'
00149 return 0
00150
00151 def rtactivate(nameserver, tags, tree):
00152 def activate_action(object, ec_index):
00153 object.activate_in_ec(ec_index)
00154 for tag in tags:
00155
00156
00157 exec_flag = True
00158 if tag.attributes.get(u'if'):
00159 val = tag.attributes.get(u'if').value
00160 arg = val.split(" ")[1].strip(")")
00161 exec_flag = get_flag_from_argv(arg)
00162 if tag.attributes.get(u'unless'):
00163 val = tag.attributes.get(u'unless').value
00164 arg = val.split(" ")[1].strip(")")
00165 exec_flag = not get_flag_from_argv(arg)
00166 if not exec_flag:
00167 continue
00168
00169 cmd_path = nameserver+"/"+tag.attributes.get("component").value
00170 full_path = path.cmd_path_to_full_path(cmd_path)
00171 full_path = replace_arg_tag_by_env(full_path)
00172
00173 try:
00174 state = wait_component(full_path, tree)
00175 if state == 'Active':
00176 continue
00177 else:
00178 print >>sys.stderr, "[rtmlaunch] Activate <-",state,full_path
00179 except Exception, e:
00180 print >>sys.stderr, '\033[31m[rtmlaunch] Could not Activate (', cmd_path, ') : ', e,'\033[0m'
00181 return 1
00182 try:
00183 options = optparse.Values({"ec_index": 0, 'verbose': False})
00184 try :
00185 state_control_base.alter_component_state(activate_action, cmd_path, full_path, options, tree=tree)
00186 except Exception, e:
00187 state_control_base.alter_component_states(activate_action, [(cmd_path, full_path)], options, tree=tree)
00188 except Exception, e:
00189 print >>sys.stderr, '[rtmlaunch] {0}: {1}'.format(os.path.basename(sys.argv[0]), e)
00190 return 1
00191 return 0
00192
00193 def main():
00194 usage = '''Usage: %prog [launchfile]'''
00195 if len(sys.argv) <= 1:
00196 print >>sys.stderr, usage
00197 return 1
00198 fullpathname = sys.argv[1]
00199 print >>sys.stderr, "[rtmlaunch] starting... ",fullpathname
00200 try:
00201 parser = parse(fullpathname)
00202 nodes = parser.getElementsByTagName("launch")[0].childNodes
00203 remove_nodes = []
00204 for node in nodes:
00205 if node.nodeName == u'group':
00206 if node.attributes.get(u'if'):
00207 val = node.getAttributeNode(u'if').value
00208 arg = val.split(" ")[1].strip(")")
00209 if not get_flag_from_argv(arg):
00210 remove_nodes.append(node)
00211 if node.attributes.get(u'unless'):
00212 val = node.getAttributeNode(u'unless').value
00213 arg = val.split(" ")[1].strip(")")
00214 if get_flag_from_argv(arg):
00215 remove_nodes.append(node)
00216
00217 for remove_node in remove_nodes:
00218 nodes.remove(remove_node)
00219 except Exception,e:
00220 print e
00221 return 1
00222
00223 if os.getenv("RTCTREE_NAMESERVERS") == None:
00224 print >>sys.stderr, "[rtmlaunch] RTCTREE_NAMESERVERS is not set, use localhost:15005"
00225 nameserver = "localhost:15005"
00226 os.environ["RTCTREE_NAMESERVERS"] = nameserver
00227 else:
00228 nameserver = os.getenv("RTCTREE_NAMESERVERS")
00229
00230 print >>sys.stderr, "\033[32m[rtmlaunch] RTCTREE_NAMESERVERS", nameserver, os.getenv("RTCTREE_NAMESERVERS"), "\033[0m"
00231 print >>sys.stderr, "\033[32m[rtmlaunch] SIMULATOR_NAME", os.getenv("SIMULATOR_NAME","Simulator"), "\033[0m"
00232
00233 try:
00234 tree = rtctree.tree.RTCTree()
00235 except Exception, e:
00236 print >>sys.stderr, "\033[31m[rtmlaunch] Could not start rtmlaunch.py, Caught exception (", e, ")\033[0m"
00237
00238 try:
00239 hostname = nameserver.split(':')[0]
00240 ip_address = socket.gethostbyname(hostname)
00241 except Exception, e:
00242 print >>sys.stderr, "\033[31m[rtmlaunch] .. Could not find IP address of ", hostname, ", Caught exception (", e, ")\033[0m"
00243 print >>sys.stderr, "\033[31m[rtmlaunch] .. Please check /etc/hosts or DNS setup\033[0m"
00244 return 1
00245
00246 print >>sys.stderr, "\033[31m[rtmlaunch] .. Could not connect to NameServer at ", nameserver, ", Caught exception (", e, ")\033[0m"
00247 print >>sys.stderr, "\033[31m[rtmlaunch] .. Please make sure that you have NameServer running at %s/`\033[0m"%(nameserver)
00248 print >>sys.stderr, "\033[31m[rtmlaunch] .. You can check with `rtls %s/`\033[0m"%(nameserver)
00249 return 1
00250 while 1:
00251 print >>sys.stderr, "[rtmlaunch] check connection/activation"
00252 rtconnect(nameserver, parser.getElementsByTagName("rtconnect"), tree)
00253 rtactivate(nameserver, parser.getElementsByTagName("rtactivate"), tree)
00254 time.sleep(10)
00255 tree.add_name_server(nameserver, [])
00256 if os.getenv("RTC_CONNECTION_CHECK_ONCE") and os.getenv("RTC_CONNECTION_CHECK_ONCE").lower() == "true":
00257 print >>sys.stderr, "[rtmlaunch] break from rtmlaunch main loop."
00258 print >>sys.stderr, "[rtmlaunch] If you check the rtc connection in the while loop, real-time loop becomes slow."
00259 break
00260 def get_flag_from_argv(arg):
00261 for a in sys.argv:
00262 if arg in a:
00263 return True if 'true' in a.split("=")[1] else False
00264
00265
00266
00267