def load(self, argv): ''' @param argv: the list with argv parameter needed to load the launch file. The name and value are separated by C{:=} @type argv: C{[str]} @return: True, if the launch file was loaded @rtype: boolean @raise LaunchConfigException: on load errors ''' try: roscfg = roslaunch.ROSLaunchConfig() loader = roslaunch.XmlLoader() self.argv = self.resolveArgs(argv) loader.load(self.Filename, roscfg, verbose=False, argv=self.argv) self.__roscfg = roscfg nm.filewatcher().add_launch(self.__masteruri, self.__launchFile, self.__launch_id, self.included_files(self.Filename)) if not nm.is_local(get_hostname(self.__masteruri)): files = self.included_files(self.Filename, regexp_retruns=[QRegExp("\\bdefault\\b"), QRegExp("\\bvalue=.*pkg:\/\/\\b"), QRegExp("\\bvalue=.*package:\/\/\\b"), QRegExp("\\bvalue=.*\$\(find\\b"), QRegExp("\\bargs=.*\$\(find\\b")]) nm.file_watcher_param().add_launch(self.__masteruri, self.__launchFile, self.__launch_id, files) except roslaunch.XmlParseException, e: test = list(re.finditer(r"environment variable '\w+' is not set", utf8(e))) message = utf8(e) if test: message = ''.join([message, '\n', 'environment substitution is not supported, use "arg" instead!']) raise LaunchConfigException(message)
def load(self, argv): ''' @param argv: the list with argv parameter needed to load the launch file. The name and value are separated by C{:=} @type argv: C{[str]} @return: True, if the launch file was loaded @rtype: boolean @raise LaunchConfigException: on load errors ''' try: roscfg = roslaunch.ROSLaunchConfig() loader = roslaunch.XmlLoader() self.argv = self.resolveArgs(argv) loader.load(self.Filename, roscfg, verbose=False, argv=self.argv) self.__roscfg = roscfg nm.filewatcher().add_launch(self.__masteruri, self.__launchFile, self.__launch_id, self.included_files(self.Filename)) if not nm.is_local(get_hostname(self.__masteruri)): files = self.included_files(self.Filename) # regexp_list=[QRegExp("\\bdefault\\b"), # QRegExp("\\bvalue=.*pkg:\/\/\\b"), # QRegExp("\\bvalue=.*package:\/\/\\b"), # QRegExp("\\bvalue=.*\$\(find\\b")]) nm.file_watcher_param().add_launch(self.__masteruri, self.__launchFile, self.__launch_id, files) except roslaunch.XmlParseException, e: test = list(re.finditer(r"environment variable '\w+' is not set", str(e))) message = str(e) if test: message = ''.join([message, '\n', 'environment substitution is not supported, use "arg" instead!']) raise LaunchConfigException(message)
def __init__(self, launch_file, package=None, masteruri=None, argv=[]): ''' Creates the LaunchConfig object. The launch file will be not loaded on creation, first on request of Roscfg value. @param launch_file: The absolute or relative path with the launch file. By using relative path a package must be valid for remote launches. @type launch_file: C{str} @param package: the package containing the launch file. If None the launch_file will be used to determine the launch file. No remote launches a possible without a valid package. @type package: C{str} or C{None} @param masteruri: The URL of the ROS master. @type masteruri: C{str} or C{None} @param argv: the list the arguments needed for loading the given launch file @type argv: C{[str]} @raise roslaunch.XmlParseException: if the launch file can't be found. ''' QObject.__init__(self) self.__launchFile = launch_file self.__package = package_name(os.path.dirname( self.__launchFile))[0] if package is None else package self.__masteruri = masteruri if masteruri is not None else 'localhost' self.__roscfg = None self.argv = argv self.__reqTested = False self.__argv_values = dict() self.global_param_done = [ ] # masteruri's where the global parameters are registered self.hostname = get_hostname(self.__masteruri) self.__launch_id = '%.9f' % time.time() nm.filewatcher().add_launch(self.__masteruri, self.__launchFile, self.__launch_id, [self.__launchFile])
def __init__(self, launch_file, package=None, masteruri=None, argv=[]): ''' Creates the LaunchConfig object. The launch file will be not loaded on creation, first on request of Roscfg value. @param launch_file: The absolute or relative path with the launch file. By using relative path a package must be valid for remote launches. @type launch_file: C{str} @param package: the package containing the launch file. If None the launch_file will be used to determine the launch file. No remote launches a possible without a valid package. @type package: C{str} or C{None} @param masteruri: The URL of the ROS master. @type masteruri: C{str} or C{None} @param argv: the list the arguments needed for loading the given launch file @type argv: C{[str]} @raise roslaunch.XmlParseException: if the launch file can't be found. ''' QObject.__init__(self) self.__launchFile = launch_file self.__package = package_name(os.path.dirname(self.__launchFile))[0] if package is None else package self.__masteruri = masteruri if masteruri is not None else 'localhost' self.__roscfg = None self.argv = argv self.__reqTested = False self.__argv_values = dict() self.global_param_done = [] # masteruri's where the global parameters are registered self.hostname = get_hostname(self.__masteruri) self.__launch_id = '%.9f' % time.time() nm.filewatcher().add_launch(self.__masteruri, self.__launchFile, self.__launch_id, [self.__launchFile])
def updateTypeView(cls, service, item): ''' Updates the representation of the column contains the type of the service. @param service: the service data @type service: U{master_discovery_fkie.ServiceInfo<http://docs.ros.org/kinetic/api/master_discovery_fkie/html/modules.html#master_discovery_fkie.master_info.ServiceInfo>} @param item: corresponding item in the model @type item: L{ServiceItem} ''' try: if service.isLocal and service.type: service_class = service.get_service_class(nm.is_local(get_hostname(service.uri))) item.setText(service_class._type) elif service.type: item.setText(service.type) else: item.setText('unknown type') # removed tooltip for clarity !!! # tooltip = '' # tooltip = ''.join([tooltip, '<h4>', service_class._type, '</h4>']) # tooltip = ''.join([tooltip, '<b><u>', 'Request', ':</u></b>']) # tooltip = ''.join([tooltip, '<dl><dt>', utf8(service_class._request_class.__slots__), '</dt></dl>']) # # tooltip = ''.join([tooltip, '<b><u>', 'Response', ':</u></b>']) # tooltip = ''.join([tooltip, '<dl><dt>', utf8(service_class._response_class.__slots__), '</dt></dl>']) # # item.setToolTip(''.join(['<div>', tooltip, '</div>'])) item.setToolTip('') except: if not service.isLocal: tooltip = ''.join(['<h4>', 'Service type is not available due to he running on another host.', '</h4>']) item.setToolTip(''.join(['<div>', tooltip, '</div>']))
def mastername(self, masteruri, address=None): with self.mutex: for m in self._masters: if m.masteruri == masteruri: if address is not None: if m.has_address(address): return m.get_mastername() else: return m.get_mastername() return get_hostname(masteruri)
def _prepareROSMaster(cls, masteruri): if masteruri is None: masteruri = masteruri_from_ros() # start roscore, if needed try: if not os.path.isdir(nm.ScreenHandler.LOG_PATH): os.makedirs(nm.ScreenHandler.LOG_PATH) socket.setdefaulttimeout(3) master = xmlrpclib.ServerProxy(masteruri) master.getUri(rospy.get_name()) # restart ROSCORE on different masteruri?, not now... # master_uri = master.getUri(rospy.get_name()) # if masteruri != master_uri[2]: # # kill the local roscore... # raise except: # run a roscore master_host = get_hostname(masteruri) if nm.is_local(master_host, True): master_port = get_port(masteruri) new_env = dict(os.environ) new_env['ROS_MASTER_URI'] = masteruri ros_hostname = NameResolution.get_ros_hostname(masteruri) if ros_hostname: new_env['ROS_HOSTNAME'] = ros_hostname cmd_args = '%s roscore --port %d' % (nm.ScreenHandler.getSceenCmd('/roscore--%d' % master_port), master_port) for n in [1, 2, 3, 4]: try: if n == 1: print("Launch ROS Master in screen ...") SupervisedPopen(shlex.split(cmd_args), env=new_env, object_id="ROSCORE", description="Start roscore") elif n == 2: print("ROS Master takes too long for start, wait for next 10 sec ...") elif n == 3: print("A really slow start, wait for last 10 sec ...") # wait for roscore to avoid connection problems while init_node result = -1 count = 1 while result == -1 and count < 11: try: master = xmlrpclib.ServerProxy(masteruri) result, _, _ = master.getUri(rospy.get_name()) # _:=uri, msg return except Exception: time.sleep(1) count += 1 if n == 4 and count >= 11: raise StartException('Cannot connect to ROS-Master: %s\n--> please run "roscore" manually!' % utf8(masteruri)) except Exception as e: raise Exception("Error while call '%s': %s" % (cmd_args, utf8(e))) else: raise Exception("ROS master '%s' is not reachable" % masteruri) finally: socket.setdefaulttimeout(None)
def _prepareROSMaster(cls, masteruri): if masteruri is None: masteruri = masteruri_from_ros() # start roscore, if needed try: if not os.path.isdir(nm.ScreenHandler.LOG_PATH): os.makedirs(nm.ScreenHandler.LOG_PATH) socket.setdefaulttimeout(3) master = xmlrpclib.ServerProxy(masteruri) master.getUri(rospy.get_name()) # restart ROSCORE on different masteruri?, not now... # master_uri = master.getUri(rospy.get_name()) # if masteruri != master_uri[2]: # # kill the local roscore... # raise except: # run a roscore master_host = get_hostname(masteruri) if nm.is_local(master_host, True): master_port = get_port(masteruri) new_env = dict(os.environ) new_env['ROS_MASTER_URI'] = masteruri ros_hostname = NameResolution.get_ros_hostname(masteruri) if ros_hostname: new_env['ROS_HOSTNAME'] = ros_hostname cmd_args = '%s roscore --port %d' % (nm.ScreenHandler.getSceenCmd('/roscore--%d' % master_port), master_port) for n in [1, 2, 3, 4]: try: if n == 1: print("Launch ROS Master in screen ...") SupervisedPopen(shlex.split(cmd_args), env=new_env, object_id="ROSCORE", description="Start roscore") elif n == 2: print("ROS Master takes too long for start, wait for next 10 sec ...") elif n == 3: print("A really slow start, wait for last 10 sec ...") # wait for roscore to avoid connection problems while init_node result = -1 count = 1 while result == -1 and count < 11: try: master = xmlrpclib.ServerProxy(masteruri) result, _, _ = master.getUri(rospy.get_name()) # _:=uri, msg return except Exception: time.sleep(1) count += 1 if n == 4 and count >= 11: raise StartException('Cannot connect to ROS-Master: %s\n--> please run "roscore" manually!' % utf8(masteruri)) except Exception as e: raise Exception("Error while call '%s': %s" % (cmd_args, utf8(e))) else: raise Exception("ROS master '%s' is not reachable" % masteruri) finally: socket.setdefaulttimeout(None)
def _prepareROSMaster(cls, masteruri): if not masteruri: masteruri = masteruri_from_ros() # start roscore, if needed try: if not os.path.isdir(ScreenHandler.LOG_PATH): os.makedirs(ScreenHandler.LOG_PATH) socket.setdefaulttimeout(3) master = xmlrpclib.ServerProxy(masteruri) master.getUri(rospy.get_name()) except: # run a roscore master_host = get_hostname(masteruri) if cls.is_local(master_host, True): print "Start ROS-Master with", masteruri, "..." master_port = get_port(masteruri) new_env = dict(os.environ) new_env['ROS_MASTER_URI'] = masteruri ros_hostname = get_ros_hostname(masteruri) if ros_hostname: new_env['ROS_HOSTNAME'] = ros_hostname cmd_args = '%s roscore --port %d' % (ScreenHandler.getSceenCmd( '/roscore--%d' % master_port), master_port) try: subprocess.Popen(shlex.split(cmd_args), env=new_env) # wait for roscore to avoid connection problems while init_node result = -1 count = 1 while result == -1 and count < 11: try: print " retry connect to ROS master", count, '/', 10 master = xmlrpclib.ServerProxy(masteruri) result, _, _ = master.getUri( rospy.get_name()) # _:=uri, msg except: time.sleep(1) count += 1 if count >= 11: raise StartException( 'Cannot connect to the ROS-Master: ' + str(masteruri)) except Exception as e: import sys print >> sys.stderr, e raise else: raise Exception("ROS master '%s' is not reachable" % masteruri) finally: socket.setdefaulttimeout(None)
def _prepareROSMaster(cls, masteruri): if not masteruri: masteruri = masteruri_from_ros() # start roscore, if needed try: if not os.path.isdir(ScreenHandler.LOG_PATH): os.makedirs(ScreenHandler.LOG_PATH) socket.setdefaulttimeout(3) master = xmlrpclib.ServerProxy(masteruri) master.getUri(rospy.get_name()) except: # run a roscore master_host = get_hostname(masteruri) if cls.is_local(master_host, True): print "Start ROS-Master with", masteruri, "..." master_port = get_port(masteruri) new_env = dict(os.environ) new_env['ROS_MASTER_URI'] = masteruri ros_hostname = get_ros_hostname(masteruri) if ros_hostname: new_env['ROS_HOSTNAME'] = ros_hostname cmd_args = '%s roscore --port %d' % (ScreenHandler.getSceenCmd('/roscore--%d' % master_port), master_port) try: subprocess.Popen(shlex.split(cmd_args), env=new_env) # wait for roscore to avoid connection problems while init_node result = -1 count = 1 while result == -1 and count < 11: try: print " retry connect to ROS master", count, '/', 10 master = xmlrpclib.ServerProxy(masteruri) result, _, _ = master.getUri(rospy.get_name()) # _:=uri, msg except: time.sleep(1) count += 1 if count >= 11: raise StartException('Cannot connect to the ROS-Master: ' + str(masteruri)) except Exception as e: import sys print >> sys.stderr, e raise else: raise Exception("ROS master '%s' is not reachable" % masteruri) finally: socket.setdefaulttimeout(None)
def __get_ip(self): try: # get the IP of the master uri result = getaddrinfo(get_hostname(self.master.uri), None) ips = [] for r in result: if r[0] == AF_INET6: (_family, _socktype, _proto, _canonname, (ip, _port, _flow, _scope)) = r else: (_family, _socktype, _proto, _canonname, (ip, _port)) = r if self.master_ip is None and ip: self.master_ip = '' if ip and ip not in ips: self.master_ip = ' '.join([self.master_ip, ip]) ips.append(ip) # self.updateNameView(self.master, self.quality, self) except: import traceback print traceback.format_exc(1)
def get_ros_hostname(url): ''' Returns the host name used in a url, if it is a name. If it is an IP an empty string will be returned. @return: host or '' if url is an IP or invalid @rtype: C{str} ''' hostname = get_hostname(url) if hostname is not None: if hostname != 'localhost': if '.' not in hostname and ':' not in hostname: # ROS resolves the 'localhost' to local hostname local_hostname = 'localhost' try: local_hostname = socket.gethostname() except: pass if hostname != local_hostname: return hostname return ''
def get_ros_hostname(cls, url): ''' Returns the host name used in a url, if it is a name. If it is an IP an empty string will be returned. @return: host or '' if url is an IP or invalid @rtype: C{str} ''' hostname = get_hostname(url) if hostname is not None: if hostname != 'localhost': if '.' not in hostname and ':' not in hostname: local_hostname = 'localhost' try: # ROS resolves the 'localhost' to local hostname local_hostname = socket.gethostname() except: pass if hostname != local_hostname: return hostname return ''
def __get_ip(self): try: # get the IP of the master uri result = getaddrinfo(get_hostname(self.master.uri), None) ips = [] for r in result: if r[0] == AF_INET6: (_family, _socktype, _proto, _canonname, (ip, _port, _flow, _scope)) = r else: (_family, _socktype, _proto, _canonname, (ip, _port)) = r if self.master_ip is None and ip: self.master_ip = '' if ip and ip not in ips: self.master_ip = ' '.join([self.master_ip, ip]) ips.append(ip) # self.updateNameView(self.master, self.quality, self) except: import traceback print traceback.format_exc(1)
def updateMaster(self, master): ''' Updates the information of the ros master. If the ROS master not exists, it will be added. @param master: the ROS master to update @type master: U{master_discovery_fkie.msg.ROSMaster<http://docs.ros.org/api/multimaster_msgs_fkie/html/msg/ROSMaster.html>} ''' # remove master, if his name was changed but not the ROS master URI root = self.invisibleRootItem() for i in reversed(range(root.rowCount())): masterItem = root.child(i) if masterItem.master.uri == master.uri and masterItem.master.name != master.name: root.removeRow(i) try: del self.pyqt_workaround[masterItem.master.name] except: pass break # update or add a the item root = self.invisibleRootItem() doAddItem = True is_local = nm.is_local(get_hostname(master.uri)) for index in range(root.rowCount()): masterItem = root.child(index, self.COL_NAME) if (masterItem == master.name): # update item masterItem.master = master masterItem.updateMasterView(root) doAddItem = False break elif (masterItem > master.name): self.addRow(master, is_local, root, index) doAddItem = False break if doAddItem: self.addRow(master, is_local, root, -1)
def updateMaster(self, master): ''' Updates the information of the ros master. If the ROS master not exists, it will be added. @param master: the ROS master to update @type master: U{master_discovery_fkie.msg.ROSMaster<http://docs.ros.org/api/multimaster_msgs_fkie/html/msg/ROSMaster.html>} ''' # remove master, if his name was changed but not the ROS master URI root = self.invisibleRootItem() for i in reversed(range(root.rowCount())): masterItem = root.child(i) if masterItem.master.uri == master.uri and masterItem.master.name != master.name: root.removeRow(i) try: del self.pyqt_workaround[masterItem.master.name] except: pass break # update or add a the item root = self.invisibleRootItem() doAddItem = True is_local = nm.is_local(get_hostname(master.uri)) for index in range(root.rowCount()): masterItem = root.child(index, self.COL_NAME) if (masterItem == master.name): # update item masterItem.master = master masterItem.updateMasterView(root) doAddItem = False break elif (masterItem > master.name): self.addRow(master, is_local, root, index) doAddItem = False break if doAddItem: self.addRow(master, is_local, root, -1)
def updateTypeView(cls, service, item): ''' Updates the representation of the column contains the type of the service. @param service: the service data @type service: U{master_discovery_fkie.ServiceInfo<http://docs.ros.org/kinetic/api/master_discovery_fkie/html/modules.html#master_discovery_fkie.master_info.ServiceInfo>} @param item: corresponding item in the model @type item: L{ServiceItem} ''' try: if service.isLocal and service.type: service_class = service.get_service_class( nm.is_local(get_hostname(service.uri))) item.setText(service_class._type) elif service.type: item.setText(service.type) else: item.setText('unknown type') # removed tooltip for clarity !!! # tooltip = '' # tooltip = ''.join([tooltip, '<h4>', service_class._type, '</h4>']) # tooltip = ''.join([tooltip, '<b><u>', 'Request', ':</u></b>']) # tooltip = ''.join([tooltip, '<dl><dt>', str(service_class._request_class.__slots__), '</dt></dl>']) # # tooltip = ''.join([tooltip, '<b><u>', 'Response', ':</u></b>']) # tooltip = ''.join([tooltip, '<dl><dt>', str(service_class._response_class.__slots__), '</dt></dl>']) # # item.setToolTip(''.join(['<div>', tooltip, '</div>'])) item.setToolTip('') except: if not service.isLocal: tooltip = ''.join([ '<h4>', 'Service type is not available due to he running on another host.', '</h4>' ]) item.setToolTip(''.join(['<div>', tooltip, '</div>']))
def init_globals(masteruri): ''' :return: True if the masteruri referred to localhost :rtype: bool ''' # initialize the global handler global _SSH_HANDLER global _SCREEN_HANDLER global _START_HANDLER global _NAME_RESOLUTION global _HISTORY global _FILE_WATCHER global _FILE_WATCHER_PARAM _SSH_HANDLER = SSHhandler() _SCREEN_HANDLER = ScreenHandler() _START_HANDLER = StartHandler() _NAME_RESOLUTION = NameResolution() _HISTORY = History() _FILE_WATCHER = FileWatcher() _FILE_WATCHER_PARAM = FileWatcher() # test where the roscore is running (local or remote) __is_local('localhost') # fill cache return __is_local(get_hostname(masteruri)) # fill cache
def init_globals(masteruri): ''' :return: True if the masteruri referred to localhost :rtype: bool ''' # initialize the global handler global _SSH_HANDLER global _SCREEN_HANDLER global _START_HANDLER global _NAME_RESOLUTION global _HISTORY global _FILE_WATCHER global _FILE_WATCHER_PARAM _SSH_HANDLER = SSHhandler() _SCREEN_HANDLER = ScreenHandler() _START_HANDLER = StartHandler() _NAME_RESOLUTION = NameResolution() _HISTORY = History() _FILE_WATCHER = FileWatcher() _FILE_WATCHER_PARAM = FileWatcher() # test where the roscore is running (local or remote) __is_local('localhost') # fill cache return __is_local(get_hostname(masteruri)) # fill cache
def on_save_profile(self, masteruri='', path=None): ''' Saves the current environment to a node manager profile. :param path: the pach the file to save :type path: str :param masteruri: If not empty, save the profile only for given master :type masteruri: str ''' try: if path is None: path = self.get_profile_file() if path is None: return rospy.loginfo("Save profile %s" % path) import yaml content = {} for muri, master in self._main_window.masters.items(): if not masteruri or masteruri == muri: running_nodes = master.getRunningNodesIfLocal() configs = {} md_param = {} ms_param = {} zc_param = {} smuri = muri addr = nm.nameres().address(smuri) hostname = get_hostname(smuri) mastername = '' if nm.is_local(addr): smuri = smuri.replace(hostname, '$LOCAL$') addr = '$LOCAL$' else: mastername = nm.nameres().mastername(smuri, nm.nameres().address(smuri)) for node_name in running_nodes.keys(): node_items = master.getNode(node_name) for node in node_items: if node.is_running() and node.launched_cfg is not None: # node.has_launch_cfgs(node.cfgs): cfg = node.launched_cfg if isinstance(node.launched_cfg, (str, unicode)): # it is default config cfg = node.launched_cfg.replace("/%s" % hostname, '/$LOCAL$').rstrip('/run') else: # it is a loaded launch file, get the filename cfg = to_url(node.launched_cfg.Filename) if cfg not in configs: configs[cfg] = {'nodes': []} configs[cfg]['nodes'].append(node_name) elif node_name.endswith('master_discovery'): md_param = get_rosparam('master_discovery', muri) elif node_name.endswith('master_sync'): ms_param = get_rosparam('master_sync', muri) elif node_name.endswith('zeroconf'): zc_param = get_rosparam('zeroconf', muri) elif node_name.endswith('default_cfg'): # store parameter for default configuration nn = node_name.replace("/%s" % hostname, '/$LOCAL$') if nn not in configs: configs[nn] = {'nodes': []} configs[nn]['params'] = get_rosparam(node_name, muri) configs[nn]['default'] = True # store arguments for launchfiles for a, b in master.launchfiles.items(): resolved_a = to_url(a) if resolved_a not in configs: if resolved_a.endswith('default_cfg/run'): pass else: configs[resolved_a] = {} configs[resolved_a]['default'] = False configs[resolved_a]['argv'] = b.argv # fill the configuration content for yaml as dictionary content[smuri] = {'mastername': mastername, 'address': addr, 'configs': configs} if md_param: content[smuri]['master_discovery'] = md_param if ms_param: content[smuri]['master_sync'] = ms_param if zc_param: content[smuri]['zeroconf'] = zc_param text = yaml.dump(content, default_flow_style=False) with open(path, 'w+') as f: f.write(text) except Exception as e: import traceback print utf8(traceback.format_exc(3)) MessageBox.warning(self, "Save profile Error", 'Error while save profile', utf8(e))
def on_save_profile(self, masteruri='', path=None): ''' Saves the current environment to a node manager profile. :param path: the pach the file to save :type path: str :param masteruri: If not empty, save the profile only for given master :type masteruri: str ''' try: if path is None: path = self.get_profile_file() if path is None: return rospy.loginfo("Save profile %s" % path) import yaml content = {} for muri, master in self._main_window.masters.items(): if not masteruri or masteruri == muri: running_nodes = master.getRunningNodesIfLocal() configs = {} md_param = {} ms_param = {} zc_param = {} smuri = muri addr = nm.nameres().address(smuri) hostname = get_hostname(smuri) mastername = '' if nm.is_local(addr): smuri = smuri.replace(hostname, '$LOCAL$') addr = '$LOCAL$' else: mastername = nm.nameres().mastername( smuri, nm.nameres().address(smuri)) for node_name in running_nodes.keys(): node_items = master.getNode(node_name) for node in node_items: if node.is_running( ) and node.launched_cfg is not None: # node.has_launch_cfgs(node.cfgs): cfg = node.launched_cfg if isinstance(node.launched_cfg, (str, unicode)): # it is default config cfg = node.launched_cfg.replace( "/%s" % hostname, '/$LOCAL$').rstrip('/run') else: # it is a loaded launch file, get the filename cfg = to_url(node.launched_cfg.Filename) if cfg not in configs: configs[cfg] = {'nodes': []} configs[cfg]['nodes'].append(node_name) elif node_name.endswith('master_discovery'): md_param = get_rosparam( 'master_discovery', muri) elif node_name.endswith('master_sync'): ms_param = get_rosparam('master_sync', muri) elif node_name.endswith('zeroconf'): zc_param = get_rosparam('zeroconf', muri) elif node_name.endswith('default_cfg'): # store parameter for default configuration nn = node_name.replace("/%s" % hostname, '/$LOCAL$') if nn not in configs: configs[nn] = {'nodes': []} configs[nn]['params'] = get_rosparam( node_name, muri) configs[nn]['default'] = True # store arguments for launchfiles for a, b in master.launchfiles.items(): resolved_a = to_url(a) if resolved_a not in configs: if resolved_a.endswith('default_cfg/run'): pass else: configs[resolved_a] = {} configs[resolved_a]['default'] = False configs[resolved_a]['argv'] = b.argv # fill the configuration content for yaml as dictionary content[smuri] = { 'mastername': mastername, 'address': addr, 'configs': configs } if md_param: content[smuri]['master_discovery'] = md_param if ms_param: content[smuri]['master_sync'] = ms_param if zc_param: content[smuri]['zeroconf'] = zc_param text = yaml.dump(content, default_flow_style=False) with open(path, 'w+') as f: f.write(text) except Exception as e: import traceback print traceback.format_exc(3) WarningMessageBox(QMessageBox.Warning, "Save profile Error", 'Error while save profile', str(e)).exec_()
def on_load_profile_file(self, path): ''' Load the profile file. :param path: the path of the profile file. :type path: str ''' rospy.loginfo("Load profile %s" % path) self.progressBar.setValue(0) self.setVisible(True) self.setWindowTitle("%s profile started" % os.path.basename(path).rstrip('.nmprofile')) hasstart = False if path: try: import yaml with open(path, 'r') as f: # print yaml.load(f.read()) content = yaml.load(f.read()) if not isinstance(content, dict): raise Exception("Mailformed profile: %s" % os.path.basename(path)) for muri, master_dict in content.items(): local_hostname = get_hostname( self._main_window.getMasteruri()) rmuri = muri.replace('$LOCAL$', local_hostname) master = self._main_window.getMaster(rmuri) running_nodes = master.getRunningNodesIfLocal() usr = None self._current_profile[rmuri] = set() if 'user' in master_dict: usr = master_dict['user'] if master_dict['mastername'] and master_dict[ 'mastername']: nm.nameres().add_master_entry( master.masteruri, master_dict['mastername'], master_dict['address']) hostname = master_dict['address'].replace( '$LOCAL$', local_hostname) if 'master_discovery' in master_dict: self._start_node_from_profile( master, hostname, 'master_discovery_fkie', 'master_discovery', usr, cfg=master_dict['master_discovery']) self._current_profile[rmuri].add( '/master_discovery') if 'master_sync' in master_dict: self._start_node_from_profile( master, hostname, 'master_sync_fkie', 'master_sync', usr, cfg=master_dict['master_sync']) self._current_profile[rmuri].add('/master_sync') if 'zeroconf' in master_dict: self._start_node_from_profile( master, hostname, 'master_discovery_fkie', 'zeroconf', usr, cfg=master_dict['zeroconf']) self._current_profile[rmuri].add('/zeroconf') try: do_start = [] do_not_stop = { '/rosout', rospy.get_name(), '/node_manager', '/master_discovery', '/master_sync', '*default_cfg', '/zeroconf' } configs = master_dict['configs'] conf_set = set() for cfg_name, cmdict in configs.items(): cfg_name = cfg_name.replace( '$LOCAL$', local_hostname) if cfg_name.startswith("pkg://"): cfg_name = os.path.abspath( resolve_url(cfg_name)) conf_set.add(cfg_name) reload_launch = True argv = [] is_default = False if 'default' in cmdict: if cmdict['default']: # it is a default configuration, test for load or not is_default = True if 'argv_used' in cmdict['params']: argv = cmdict['params'][ 'argv_used'] if cfg_name in master.default_cfgs: reload_launch = False if argv: params = get_rosparam( cfg_name, rmuri) if 'argv_used' in params: reload_launch = set( params['argv_used'] ) != set(argv) if reload_launch: self._main_window.on_load_launch_as_default_bypkg( cmdict['params']['package'], cmdict['params'] ['launch_file'], master, argv, local_hostname) else: do_not_stop.add(cfg_name) elif 'argv' in cmdict: if 'argv' in cmdict: argv = cmdict['argv'] # do we need to load to load/reload launch file if cfg_name in master.launchfiles: reload_launch = set( master.launchfiles[cfg_name].argv ) != set(argv) if reload_launch: self._main_window.launch_dock.load_file( cfg_name, argv, master.masteruri) if 'nodes' in cmdict: self._current_profile[rmuri].update( cmdict['nodes']) force_start = True cfg = cfg_name if not is_default else roslib.names.ns_join( cfg_name, 'run') if not reload_launch: force_start = False do_not_stop.update(set( cmdict['nodes'])) do_start.append( (reload_launch, cfg, cmdict['nodes'], force_start)) else: do_start.append( (reload_launch, cfg, cmdict['nodes'], force_start)) # close unused configurations for lfile in set( master.launchfiles.keys()) - conf_set: master._close_cfg(lfile) master.stop_nodes_by_name(running_nodes.keys(), True, do_not_stop) for reload_launch, cfg, nodes, force_start in do_start: if nodes: hasstart = True if reload_launch: master.start_nodes_after_load_cfg( cfg.rstrip('/run'), list(nodes), force_start) else: master.start_nodes_by_name( list(nodes), cfg, force_start) except Exception as ml: import traceback print traceback.format_exc(1) rospy.logwarn( "Can not load launch file for %s: %s" % (muri, ml)) except Exception as e: import traceback print traceback.format_exc(1) WarningMessageBox(QMessageBox.Warning, "Load profile error", 'Error while load profile', str(e)).exec_() if not hasstart: self.update_progress() else: QTimer.singleShot(1000, self.update_progress)
def address(self, masteruri): with self.mutex: for m in self._masters: if m.masteruri == masteruri or m.has_mastername(masteruri): return m.get_address() return get_hostname(masteruri)
def on_load_profile_file(self, path): ''' Load the profile file. :param path: the path of the profile file. :type path: str ''' rospy.loginfo("Load profile %s" % path) self.progressBar.setValue(0) self.setVisible(True) self.setWindowTitle("%s profile started" % os.path.basename(path).rstrip('.nmprofile')) hasstart = False if path: try: import yaml with open(path, 'r') as f: # print yaml.load(f.read()) content = yaml.load(f.read()) if not isinstance(content, dict): raise Exception("Mailformed profile: %s" % os.path.basename(path)) for muri, master_dict in content.items(): local_hostname = get_hostname(self._main_window.getMasteruri()) rmuri = muri.replace('$LOCAL$', local_hostname) master = self._main_window.getMaster(rmuri) running_nodes = master.getRunningNodesIfLocal() usr = None self._current_profile[rmuri] = set() if 'user' in master_dict: usr = master_dict['user'] if master_dict['mastername'] and master_dict['mastername']: nm.nameres().add_master_entry(master.masteruri, master_dict['mastername'], master_dict['address']) hostname = master_dict['address'].replace('$LOCAL$', local_hostname) if 'master_discovery' in master_dict: self._start_node_from_profile(master, hostname, 'master_discovery_fkie', 'master_discovery', usr, cfg=master_dict['master_discovery']) self._current_profile[rmuri].add('/master_discovery') if 'master_sync' in master_dict: self._start_node_from_profile(master, hostname, 'master_sync_fkie', 'master_sync', usr, cfg=master_dict['master_sync']) self._current_profile[rmuri].add('/master_sync') if 'zeroconf' in master_dict: self._start_node_from_profile(master, hostname, 'master_discovery_fkie', 'zeroconf', usr, cfg=master_dict['zeroconf']) self._current_profile[rmuri].add('/zeroconf') try: do_start = [] do_not_stop = {'/rosout', rospy.get_name(), '/node_manager', '/master_discovery', '/master_sync', '*default_cfg', '/zeroconf'} configs = master_dict['configs'] conf_set = set() for cfg_name, cmdict in configs.items(): cfg_name = cfg_name.replace('$LOCAL$', local_hostname) if cfg_name.startswith("pkg://"): cfg_name = os.path.abspath(resolve_url(cfg_name)) conf_set.add(cfg_name) reload_launch = True argv = [] is_default = False if 'default' in cmdict: if cmdict['default']: # it is a default configuration, test for load or not is_default = True if 'argv_used' in cmdict['params']: argv = cmdict['params']['argv_used'] if cfg_name in master.default_cfgs: reload_launch = False if argv: params = get_rosparam(cfg_name, rmuri) if 'argv_used' in params: reload_launch = set(params['argv_used']) != set(argv) if reload_launch: self._main_window.on_load_launch_as_default_bypkg(cmdict['params']['package'], cmdict['params']['launch_file'], master, argv, local_hostname) else: do_not_stop.add(cfg_name) elif 'argv' in cmdict: if 'argv' in cmdict: argv = cmdict['argv'] # do we need to load to load/reload launch file if cfg_name in master.launchfiles: reload_launch = set(master.launchfiles[cfg_name].argv) != set(argv) if reload_launch: self._main_window.launch_dock.load_file(cfg_name, argv, master.masteruri) if 'nodes' in cmdict: self._current_profile[rmuri].update(cmdict['nodes']) force_start = True cfg = cfg_name if not is_default else roslib.names.ns_join(cfg_name, 'run') if not reload_launch: force_start = False do_not_stop.update(set(cmdict['nodes'])) do_start.append((reload_launch, cfg, cmdict['nodes'], force_start)) else: do_start.append((reload_launch, cfg, cmdict['nodes'], force_start)) # close unused configurations for lfile in set(master.launchfiles.keys()) - conf_set: master._close_cfg(lfile) master.stop_nodes_by_name(running_nodes.keys(), True, do_not_stop) for reload_launch, cfg, nodes, force_start in do_start: if nodes: hasstart = True if reload_launch: master.start_nodes_after_load_cfg(cfg.rstrip('/run'), list(nodes), force_start) else: master.start_nodes_by_name(list(nodes), cfg, force_start) except Exception as ml: import traceback print utf8(traceback.format_exc(1)) rospy.logwarn("Can not load launch file for %s: %s" % (muri, utf8(ml))) except Exception as e: import traceback print traceback.format_exc(1) MessageBox.warning(self, "Load profile error", 'Error while load profile', utf8(e)) if not hasstart: self.update_progress() else: QTimer.singleShot(1000, self.update_progress)