def init_cfg_path(): global CFG_PATH masteruri = masteruri_from_ros() CFG_PATH = ''.join([get_ros_home(), os.sep, 'node_manager', os.sep]) ''' Creates and runs the ROS node. ''' if not os.path.isdir(CFG_PATH): os.makedirs(CFG_PATH) return masteruri
def getDefaultRPCPort(zeroconf=False): try: from common import masteruri_from_ros masteruri = masteruri_from_ros() rospy.loginfo("ROS Master URI: %s", masteruri) from urlparse import urlparse return urlparse(masteruri).port+(600 if zeroconf else 300) except: import traceback print traceback.format_exc() return 11911 if zeroconf else 11611
def getMasteruri(self): ''' Requests the ROS master URI from the ROS master through the RPC interface and returns it. The 'materuri' attribute will be set to the requested value. @return: ROS master URI @rtype: C{str} or C{None} ''' if not hasattr(self, 'materuri') or self.materuri is None: masteruri = masteruri_from_ros() master = xmlrpclib.ServerProxy(masteruri) code, message, self.materuri = master.getUri(rospy.get_name()) return self.materuri
def init_cfg_path(): global CFG_PATH masteruri = masteruri_from_ros() CFG_PATH = ''.join([get_ros_home(), os.sep, 'node_manager', os.sep]) ''' Creates and runs the ROS node. ''' if not os.path.isdir(CFG_PATH): os.makedirs(CFG_PATH) # start ROS-Master, if not currently running StartHandler._prepareROSMaster(masteruri) return masteruri
def reload(self): ''' Loads the settings from file or sets default values if no one exists. ''' self._terminal_emulator = None self._terminal_command_arg = 'e' self._masteruri = masteruri_from_ros() self.CFG_PATH = os.path.join(get_ros_home(), 'node_manager') # loads the current configuration path. If the path was changed, a redirection # file exists with new configuration folder if not os.path.isdir(self.CFG_PATH): os.makedirs(self.CFG_PATH) self._cfg_path = self.CFG_PATH else: settings = self.qsettings( os.path.join(self.CFG_PATH, self.CFG_REDIRECT_FILE)) self._cfg_path = settings.value('cfg_path', self.CFG_PATH) # after the settings path was loaded, load other settings self._robots_path = self.ROBOTS_DIR settings = self.qsettings(self.CFG_FILE) self._default_user = settings.value('default_user', self.USER_DEFAULT) try: self._launch_history_length = int( settings.value('launch_history_length', self.LAUNCH_HISTORY_LENGTH)) except: self._launch_history_length = self.LAUNCH_HISTORY_LENGTH try: self._param_history_length = int( settings.value('param_history_length', self.PARAM_HISTORY_LENGTH)) except: self._param_history_length = self.PARAM_HISTORY_LENGTH self._current_dialog_path = self.CURRENT_DIALOG_PATH self._log_viewer = self.LOG_VIEWER self._start_remote_script = self.STARTER_SCRIPT self._respawn_script = self.RESPAWN_SCRIPT self._launch_view_file_ext = self.str2list( settings.value('launch_view_file_ext', ', '.join(self.LAUNCH_VIEW_EXT))) self._store_geometry = self.str2bool( settings.value('store_geometry', self.STORE_GEOMETRY)) self.SEARCH_IN_EXT = list( set(self.SEARCH_IN_EXT) | set(self._launch_view_file_ext)) self._autoupdate = self.str2bool( settings.value('autoupdate', self.AUTOUPDATE))
def __init__(self, name, uri, discoverer_name, monitoruri, timestamp): ''' Initialization method for the SyncThread. @param name: the name of the ROS master synchronized with. @type name: C{str} @param uri: the URI of the ROS master synchronized with @type uri: C{str} @param discoverer_name: the name of the discovery node running on ROS master synchronized with. @type discoverer_name: C{str} @param monitoruri: The URI of RPC server of the discovery node to get the ROS master state by calling a method only once. @type monitoruri: C{str} @param timestamp: The timestamp of the current state of the ROS master info. @type timestamp: C{float64} ''' # init thread threading.Thread.__init__(self) self.masterInfo = MasterInfo(name, uri, discoverer_name, monitoruri, timestamp) self.localMasteruri = masteruri_from_ros() rospy.logdebug("SyncThread[%s]: create this sync thread", self.masterInfo.name) # synchronization variables self.__cv = threading.Condition() self.__lock_info = threading.RLock() self.__sync_info = None #SyncMasterInfo with currently synchronized nodes, publisher (topic, node, nodeuri), subscriber(topic, node, nodeuri) and services self.__stop = False # a list with published topics as a tuple of (topic name, node name, node URL) self.__publisher = [] # a list with subscribed topics as a tuple of (topic name, node name, node URL) self.__subscriber = [] # a list with services as a tuple of (service name, service URL, node name, node URL) self.__services = [] self.__own_state = None #setup the interface self._loadInterface() # congestion avoidance: wait for minimum 1 sec. If an update request is received wait # for next 1 second. Force update after maximum 5 sec since first update request. self._ts_first_update_request = None self._ts_last_update_request = None self.start()
def reload(self): ''' Loads the settings from file or sets default values if no one exists. ''' self._terminal_emulator = None self._terminal_command_arg = 'e' self._masteruri = masteruri_from_ros() self.CFG_PATH = os.path.join(get_ros_home(), 'node_manager') # loads the current configuration path. If the path was changed, a redirection # file exists with new configuration folder if not os.path.isdir(self.CFG_PATH): os.makedirs(self.CFG_PATH) self._cfg_path = self.CFG_PATH else: settings = self.qsettings(os.path.join(self.CFG_PATH, self.CFG_REDIRECT_FILE)) self._cfg_path = settings.value('cfg_path', self.CFG_PATH) # after the settings path was loaded, load other settings self._robots_path = self.ROBOTS_DIR settings = self.qsettings(self.CFG_FILE) self._default_user = settings.value('default_user', self.USER_DEFAULT) settings.beginGroup('default_user_hosts') self._default_user_hosts = dict() for k in settings.childKeys(): self._default_user_hosts[k] = settings.value(k, self._default_user) settings.endGroup() try: self._launch_history_length = int(settings.value('launch_history_length', self.LAUNCH_HISTORY_LENGTH)) except: self._launch_history_length = self.LAUNCH_HISTORY_LENGTH try: self._param_history_length = int(settings.value('param_history_length', self.PARAM_HISTORY_LENGTH)) except: self._param_history_length = self.PARAM_HISTORY_LENGTH self._current_dialog_path = self.CURRENT_DIALOG_PATH self._log_viewer = self.LOG_VIEWER self._start_remote_script = self.STARTER_SCRIPT self._respawn_script = self.RESPAWN_SCRIPT self._launch_view_file_ext = self.str2list(settings.value('launch_view_file_ext', ', '.join(self.LAUNCH_VIEW_EXT))) self._store_geometry = self.str2bool(settings.value('store_geometry', self.STORE_GEOMETRY)) self.SEARCH_IN_EXT = list(set(self.SEARCH_IN_EXT) | set(self._launch_view_file_ext)) self._autoupdate = self.str2bool(settings.value('autoupdate', self.AUTOUPDATE))
def __init__(self, rpcport=11611, do_retry=True): ''' Initialize method. Creates an XML-RPC server on given port and starts this in its own thread. :param rpcport: the port number for the XML-RPC server :type rpcport: int :param do_retry: retry to create XML-RPC server :type do_retry: bool ''' self._state_access_lock = threading.RLock() self._create_access_lock = threading.RLock() self._lock = threading.RLock() self.__masteruri = masteruri_from_ros() self.__new_master_state = None self.__masteruri_rpc = None self.__mastername = None self.__cached_nodes = dict() self.__cached_services = dict() self.ros_node_name = str(rospy.get_name()) if rospy.has_param('~name'): self.__mastername = rospy.get_param('~name') self.__mastername = self.getMastername() rospy.set_param('/mastername', self.__mastername) self.__master_state = None '''the current state of the ROS master''' self.rpcport = rpcport '''the port number of the RPC server''' self._printed_errors = dict() self._last_clearup_ts = time.time() # Create an XML-RPC server self.ready = False while not self.ready and (not rospy.is_shutdown()): try: self.rpcServer = RPCThreading(('', rpcport), logRequests=False, allow_none=True) rospy.loginfo("Start RPC-XML Server at %s", self.rpcServer.server_address) self.rpcServer.register_introspection_functions() self.rpcServer.register_function(self.getListedMasterInfo, 'masterInfo') self.rpcServer.register_function(self.getListedMasterInfoFiltered, 'masterInfoFiltered') self.rpcServer.register_function(self.getMasterContacts, 'masterContacts') self._rpcThread = threading.Thread(target = self.rpcServer.serve_forever) self._rpcThread.setDaemon(True) self._rpcThread.start() self.ready = True except socket.error: if not do_retry: raise Exception(''.join(["Error while start RPC-XML server on port ", str(rpcport), ". Is a Node Manager already running?"])) rospy.logwarn(''.join(["Error while start RPC-XML server on port ", str(rpcport), ". Try again..."])) time.sleep(1) except: import traceback print traceback.format_exc() if not do_retry: raise self._master = xmlrpclib.ServerProxy(self.getMasteruri()) # === UPDATE THE LAUNCH URIS Section === # subscribe to get parameter updates rospy.loginfo("Subscribe to parameter `/roslaunch/uris`") self.__mycache_param_server = rospy.impl.paramserver.get_param_server_cache() # HACK: use own method to get the updates also for parameters in the subgroup self.__mycache_param_server.update = self.__update_param # first access, make call to parameter server self._update_launch_uris_lock = threading.RLock() self.__launch_uris = {} code, msg, value = self._master.subscribeParam(self.ros_node_name, rospy.get_node_uri(), '/roslaunch/uris') # the new timer will be created in self._update_launch_uris() self._timer_update_launch_uris = None if code == 1: for k,v in value.items(): self.__launch_uris[roslib.names.ns_join('/roslaunch/uris', k)] = v self._update_launch_uris()
def __init__(self, rpcport=11611, do_retry=True, ipv6=False): ''' Initialize method. Creates an XML-RPC server on given port and starts this in its own thread. :param rpcport: the port number for the XML-RPC server :type rpcport: int :param do_retry: retry to create XML-RPC server :type do_retry: bool :param ipv6: Use ipv6 :type ipv6: bool ''' self._state_access_lock = threading.RLock() self._create_access_lock = threading.RLock() self._lock = threading.RLock() self.__masteruri = masteruri_from_ros() self.__new_master_state = None self.__masteruri_rpc = None self.__mastername = None self.__cached_nodes = dict() self.__cached_services = dict() self.ros_node_name = str(rospy.get_name()) if rospy.has_param('~name'): self.__mastername = rospy.get_param('~name') self.__mastername = self.getMastername() rospy.set_param('/mastername', self.__mastername) self.__master_state = None '''the current state of the ROS master''' self.rpcport = rpcport '''the port number of the RPC server''' self._printed_errors = dict() self._last_clearup_ts = time.time() # Create an XML-RPC server self.ready = False while not self.ready and (not rospy.is_shutdown()): try: RPCClass = RPCThreading if ipv6: RPCClass = RPCThreadingV6 self.rpcServer = RPCClass(('', rpcport), logRequests=False, allow_none=True) rospy.loginfo("Start RPC-XML Server at %s", self.rpcServer.server_address) self.rpcServer.register_introspection_functions() self.rpcServer.register_function(self.getListedMasterInfo, 'masterInfo') self.rpcServer.register_function( self.getListedMasterInfoFiltered, 'masterInfoFiltered') self.rpcServer.register_function(self.getMasterContacts, 'masterContacts') self._rpcThread = threading.Thread( target=self.rpcServer.serve_forever) self._rpcThread.setDaemon(True) self._rpcThread.start() self.ready = True except socket.error as e: if not do_retry: raise Exception( "Error while start RPC-XML server on port %d: %s\nIs a Node Manager already running?" % (rpcport, e)) rospy.logwarn( "Error while start RPC-XML server on port %d: %s\nTry again..." % (rpcport, e)) time.sleep(1) except: import traceback print traceback.format_exc() if not do_retry: raise self._master = xmlrpclib.ServerProxy(self.getMasteruri()) # === UPDATE THE LAUNCH URIS Section === # subscribe to get parameter updates rospy.loginfo("Subscribe to parameter `/roslaunch/uris`") self.__mycache_param_server = rospy.impl.paramserver.get_param_server_cache( ) # HACK: use own method to get the updates also for parameters in the subgroup self.__mycache_param_server.update = self.__update_param # first access, make call to parameter server self._update_launch_uris_lock = threading.RLock() self.__launch_uris = {} code, msg, value = self._master.subscribeParam(self.ros_node_name, rospy.get_node_uri(), '/roslaunch/uris') # the new timer will be created in self._update_launch_uris() self._timer_update_launch_uris = None if code == 1: for k, v in value.items(): self.__launch_uris[roslib.names.ns_join('/roslaunch/uris', k)] = v self._update_launch_uris()
def runNode(cls, node, launch_config, force2host=None, masteruri=None, auto_pw_request=False, user=None, pw=None, item=None): ''' Start the node with given name from the given configuration. @param node: the name of the node (with name space) @type node: C{str} @param launch_config: the configuration containing the node @type launch_config: L{LaunchConfig} @param force2host: start the node on given host. @type force2host: L{str} @param masteruri: force the masteruri. @type masteruri: L{str} @param auto_pw_request: opens question dialog directly, use True only if the method is called from the main GUI thread @type auto_pw_request: bool @raise StartException: if the screen is not available on host. @raise Exception: on errors while resolving host @see: L{node_manager_fkie.is_local()} ''' #'print "RUN node", node, time.time() n = launch_config.getNode(node) if n is None: raise StartException(''.join(["Node '", node, "' not found!"])) env = list(n.env_args) if n.respawn: # set the respawn environment variables respawn_params = cls._get_respawn_params(rospy.names.ns_join(n.namespace, n.name), launch_config.Roscfg.params) if respawn_params['max'] > 0: env.append(('RESPAWN_MAX', '%d'%respawn_params['max'])) if respawn_params['min_runtime'] > 0: env.append(('RESPAWN_MIN_RUNTIME', '%d'%respawn_params['min_runtime'])) if respawn_params['delay'] > 0: env.append(('RESPAWN_DELAY', '%d'%respawn_params['delay'])) prefix = n.launch_prefix if not n.launch_prefix is None else '' if prefix.lower() == 'screen' or prefix.lower().find('screen ') != -1: rospy.loginfo("SCREEN prefix removed before start!") prefix = '' args = [''.join(['__ns:=', n.namespace.rstrip(rospy.names.SEP)]), ''.join(['__name:=', n.name])] if not (n.cwd is None): args.append(''.join(['__cwd:=', n.cwd])) # add remaps for remap in n.remap_args: args.append(''.join([remap[0], ':=', remap[1]])) # get host of the node host = launch_config.hostname env_loader = '' if n.machine_name: machine = launch_config.Roscfg.machines[n.machine_name] if not machine.address in ['localhost', '127.0.0.1']: host = machine.address if masteruri is None: masteruri = nm.nameres().masteruri(n.machine_name) #TODO: env-loader support? # if hasattr(machine, "env_loader") and machine.env_loader: # env_loader = machine.env_loader # set the host to the given host if not force2host is None: host = force2host # set the ROS_MASTER_URI if masteruri is None: masteruri = masteruri_from_ros() env.append(('ROS_MASTER_URI', masteruri)) abs_paths = list() # tuples of (parameter name, old value, new value) not_found_packages = list() # package names # set the global parameter if not masteruri is None and not masteruri in launch_config.global_param_done: global_node_names = cls.getGlobalParams(launch_config.Roscfg) rospy.loginfo("Register global parameter:\n %s", '\n '.join("%s%s"%(str(v)[:80],'...' if len(str(v))>80 else'') for v in global_node_names.values())) abs_paths[len(abs_paths):], not_found_packages[len(not_found_packages):] = cls._load_parameters(masteruri, global_node_names, [], user, pw, auto_pw_request) launch_config.global_param_done.append(masteruri) # add params if not masteruri is None: nodens = ''.join([n.namespace, n.name, rospy.names.SEP]) params = dict() for param, value in launch_config.Roscfg.params.items(): if param.startswith(nodens): params[param] = value clear_params = [] for cparam in launch_config.Roscfg.clear_params: if cparam.startswith(nodens): clear_params.append(cparam) rospy.loginfo("Delete parameter:\n %s", '\n '.join(clear_params)) rospy.loginfo("Register parameter:\n %s", '\n '.join("%s%s"%(str(v)[:80],'...' if len(str(v))>80 else'') for v in params.values())) abs_paths[len(abs_paths):], not_found_packages[len(not_found_packages):] = cls._load_parameters(masteruri, params, clear_params, user, pw, auto_pw_request) #'print "RUN prepared", node, time.time() if nm.is_local(host): nm.screen().testScreen() if item: cmd_type = item else: try: cmd = roslib.packages.find_node(n.package, n.type) except (Exception, roslib.packages.ROSPkgException) as e: # multiple nodes, invalid package raise StartException(''.join(["Can't find resource: ", str(e)])) # handle diferent result types str or array of string if isinstance(cmd, types.StringTypes): cmd = [cmd] cmd_type = '' if cmd is None or len(cmd) == 0: raise StartException(' '.join([n.type, 'in package [', n.package, '] not found!\n\nThe package was created?\nIs the binary executable?\n'])) if len(cmd) > 1: if auto_pw_request: # Open selection for executables, only if the method is called from the main GUI thread try: from python_qt_binding import QtGui item, result = QtGui.QInputDialog.getItem(None, ' '.join(['Multiple executables', n.type, 'in', n.package]), 'Select an executable', cmd, 0, False) if result: #open the selected screen cmd_type = item else: return except: raise StartException('Multiple executables with same name in package found!') else: err = BinarySelectionRequest(cmd, 'Multiple executables') raise nm.InteractionNeededError(err, cls.runNode, (node, launch_config, force2host, masteruri, auto_pw_request, user, pw)) else: cmd_type = cmd[0] # determine the current working path, Default: the package of the node cwd = get_ros_home() if not (n.cwd is None): if n.cwd == 'ROS_HOME': cwd = get_ros_home() elif n.cwd == 'node': cwd = os.path.dirname(cmd_type) cls._prepareROSMaster(masteruri) node_cmd = [nm.settings().respawn_script if n.respawn else '', prefix, cmd_type] cmd_args = [nm.screen().getSceenCmd(node)] cmd_args[len(cmd_args):] = node_cmd cmd_args.append(str(n.args)) cmd_args[len(cmd_args):] = args rospy.loginfo("RUN: %s", ' '.join(cmd_args)) new_env = dict(os.environ) new_env['ROS_MASTER_URI'] = masteruri # add the namespace environment parameter to handle some cases, e.g. rqt_cpp plugins if n.namespace: new_env['ROS_NAMESPACE'] = n.namespace for k, v in env: new_env[k] = v SupervisedPopen(shlex.split(str(' '.join(cmd_args))), cwd=cwd, env=new_env, id="Run node", description="Run node [%s]%s"%(str(n.package), str(n.type))) else: #'print "RUN REMOTE", node, time.time() # start remote if launch_config.PackageName is None: raise StartException(''.join(["Can't run remote without a valid package name!"])) # thus the prefix parameters while the transfer are not separated if prefix: prefix = ''.join(['"', prefix, '"']) # setup environment env_command = '' if env_loader: rospy.logwarn("env_loader in machine tag currently not supported") raise StartException("env_loader in machine tag currently not supported") if env: new_env = dict() try: for (k, v) in env: v_value, is_abs_path, found, package = cls._resolve_abs_paths(v, host, user, pw, auto_pw_request) new_env[k] = v_value if is_abs_path: abs_paths.append(('ENV', "%s=%s"%(k,v), "%s=%s"%(k,v_value))) if not found and package: not_found_packages.append(package) env_command = "env "+' '.join(["%s=%s"%(k,v) for (k, v) in new_env.items()]) except nm.AuthenticationRequest as e: raise nm.InteractionNeededError(e, cls.runNode, (node, launch_config, force2host, masteruri, auto_pw_request)) startcmd = [env_command, nm.settings().start_remote_script, '--package', str(n.package), '--node_type', str(n.type), '--node_name', str(node), '--node_respawn true' if n.respawn else ''] if not masteruri is None: startcmd.append('--masteruri') startcmd.append(masteruri) if prefix: startcmd[len(startcmd):] = ['--prefix', prefix] #rename the absolute paths in the args of the node node_args = [] try: for a in n.args.split(): a_value, is_abs_path, found, package = cls._resolve_abs_paths(a, host, user, pw, auto_pw_request) node_args.append(a_value) if is_abs_path: abs_paths.append(('ARGS', a, a_value)) if not found and package: not_found_packages.append(package) startcmd[len(startcmd):] = node_args startcmd[len(startcmd):] = args rospy.loginfo("Run remote on %s: %s", host, str(' '.join(startcmd))) #'print "RUN CALL", node, time.time() _, stdout, stderr, ok = nm.ssh().ssh_exec(host, startcmd, user, pw, auto_pw_request, close_stdin=True) output = stdout.read() error = stderr.read() stdout.close() stderr.close() #'print "RUN CALLOK", node, time.time() except nm.AuthenticationRequest as e: raise nm.InteractionNeededError(e, cls.runNode, (node, launch_config, force2host, masteruri, auto_pw_request)) if ok: if error: rospy.logwarn("ERROR while start '%s': %s", node, error) raise StartException(str(''.join(['The host "', host, '" reports:\n', error]))) if output: rospy.loginfo("STDOUT while start '%s': %s", node, output) # inform about absolute paths in parameter value if len(abs_paths) > 0: rospy.loginfo("Absolute paths found while start:\n%s", str('\n'.join([''.join([p, '\n OLD: ', ov, '\n NEW: ', nv]) for p, ov, nv in abs_paths]))) if len(not_found_packages) > 0: packages = '\n'.join(not_found_packages) raise StartException(str('\n'.join(['Some absolute paths are not renamed because following packages are not found on remote host:', packages])))
def runNode(cls, node, launch_config, force2host=None, masteruri=None, auto_pw_request=False, user=None, pw=None, item=None): ''' Start the node with given name from the given configuration. @param node: the name of the node (with name space) @type node: C{str} @param launch_config: the configuration containing the node @type launch_config: L{LaunchConfig} @param force2host: start the node on given host. @type force2host: L{str} @param masteruri: force the masteruri. @type masteruri: L{str} @param auto_pw_request: opens question dialog directly, use True only if the method is called from the main GUI thread @type auto_pw_request: bool @raise StartException: if the screen is not available on host. @raise Exception: on errors while resolving host @see: L{node_manager_fkie.is_local()} ''' #'print "RUN node", node, time.time() n = launch_config.getNode(node) if n is None: raise StartException(''.join(["Node '", node, "' not found!"])) env = list(n.env_args) if n.respawn: # set the respawn environment variables respawn_params = cls._get_respawn_params( rospy.names.ns_join(n.namespace, n.name), launch_config.Roscfg.params) if respawn_params['max'] > 0: env.append(('RESPAWN_MAX', '%d' % respawn_params['max'])) if respawn_params['min_runtime'] > 0: env.append(('RESPAWN_MIN_RUNTIME', '%d' % respawn_params['min_runtime'])) if respawn_params['delay'] > 0: env.append(('RESPAWN_DELAY', '%d' % respawn_params['delay'])) prefix = n.launch_prefix if not n.launch_prefix is None else '' if prefix.lower() == 'screen' or prefix.lower().find('screen ') != -1: rospy.loginfo("SCREEN prefix removed before start!") prefix = '' args = [ ''.join(['__ns:=', n.namespace.rstrip(rospy.names.SEP)]), ''.join(['__name:=', n.name]) ] if not (n.cwd is None): args.append(''.join(['__cwd:=', n.cwd])) # add remaps for remap in n.remap_args: args.append(''.join([remap[0], ':=', remap[1]])) # get host of the node host = launch_config.hostname env_loader = '' if n.machine_name: machine = launch_config.Roscfg.machines[n.machine_name] if not machine.address in ['localhost', '127.0.0.1']: host = machine.address if masteruri is None: masteruri = nm.nameres().masteruri(n.machine_name) #TODO: env-loader support? # if hasattr(machine, "env_loader") and machine.env_loader: # env_loader = machine.env_loader # set the host to the given host if not force2host is None: host = force2host # set the ROS_MASTER_URI if masteruri is None: masteruri = masteruri_from_ros() env.append(('ROS_MASTER_URI', masteruri)) abs_paths = list() # tuples of (parameter name, old value, new value) not_found_packages = list() # package names # set the global parameter if not masteruri is None and not masteruri in launch_config.global_param_done: global_node_names = cls.getGlobalParams(launch_config.Roscfg) rospy.loginfo( "Register global parameter:\n %s", '\n '.join( "%s%s" % (str(v)[:80], '...' if len(str(v)) > 80 else '') for v in global_node_names.values())) abs_paths[len(abs_paths):], not_found_packages[ len(not_found_packages):] = cls._load_parameters( masteruri, global_node_names, [], user, pw, auto_pw_request) launch_config.global_param_done.append(masteruri) # add params if not masteruri is None: nodens = ''.join([n.namespace, n.name, rospy.names.SEP]) params = dict() for param, value in launch_config.Roscfg.params.items(): if param.startswith(nodens): params[param] = value clear_params = [] for cparam in launch_config.Roscfg.clear_params: if cparam.startswith(nodens): clear_params.append(cparam) rospy.loginfo("Delete parameter:\n %s", '\n '.join(clear_params)) rospy.loginfo( "Register parameter:\n %s", '\n '.join( "%s%s" % (str(v)[:80], '...' if len(str(v)) > 80 else '') for v in params.values())) abs_paths[len(abs_paths):], not_found_packages[ len(not_found_packages):] = cls._load_parameters( masteruri, params, clear_params, user, pw, auto_pw_request) #'print "RUN prepared", node, time.time() if nm.is_local(host): nm.screen().testScreen() if item: cmd_type = item else: try: cmd = roslib.packages.find_node(n.package, n.type) except (Exception, roslib.packages.ROSPkgException) as e: # multiple nodes, invalid package raise StartException(''.join( ["Can't find resource: ", str(e)])) # handle diferent result types str or array of string if isinstance(cmd, types.StringTypes): cmd = [cmd] cmd_type = '' if cmd is None or len(cmd) == 0: raise StartException(' '.join([ n.type, 'in package [', n.package, '] not found!\n\nThe package was created?\nIs the binary executable?\n' ])) if len(cmd) > 1: if auto_pw_request: # Open selection for executables, only if the method is called from the main GUI thread try: from python_qt_binding import QtGui item, result = QtGui.QInputDialog.getItem( None, ' '.join([ 'Multiple executables', n.type, 'in', n.package ]), 'Select an executable', cmd, 0, False) if result: #open the selected screen cmd_type = item else: return except: raise StartException( 'Multiple executables with same name in package found!' ) else: err = BinarySelectionRequest(cmd, 'Multiple executables') raise nm.InteractionNeededError( err, cls.runNode, (node, launch_config, force2host, masteruri, auto_pw_request, user, pw)) else: cmd_type = cmd[0] # determine the current working path, Default: the package of the node cwd = get_ros_home() if not (n.cwd is None): if n.cwd == 'ROS_HOME': cwd = get_ros_home() elif n.cwd == 'node': cwd = os.path.dirname(cmd_type) cls._prepareROSMaster(masteruri) node_cmd = [ nm.settings().respawn_script if n.respawn else '', prefix, cmd_type ] cmd_args = [nm.screen().getSceenCmd(node)] cmd_args[len(cmd_args):] = node_cmd cmd_args.append(str(n.args)) cmd_args[len(cmd_args):] = args rospy.loginfo("RUN: %s", ' '.join(cmd_args)) new_env = dict(os.environ) new_env['ROS_MASTER_URI'] = masteruri # add the namespace environment parameter to handle some cases, e.g. rqt_cpp plugins if n.namespace: new_env['ROS_NAMESPACE'] = n.namespace for k, v in env: new_env[k] = v SupervisedPopen(shlex.split(str(' '.join(cmd_args))), cwd=cwd, env=new_env, id="Run node", description="Run node [%s]%s" % (str(n.package), str(n.type))) else: #'print "RUN REMOTE", node, time.time() # start remote if launch_config.PackageName is None: raise StartException(''.join( ["Can't run remote without a valid package name!"])) # thus the prefix parameters while the transfer are not separated if prefix: prefix = ''.join(['"', prefix, '"']) # setup environment env_command = '' if env_loader: rospy.logwarn( "env_loader in machine tag currently not supported") raise StartException( "env_loader in machine tag currently not supported") if env: new_env = dict() try: for (k, v) in env: v_value, is_abs_path, found, package = cls._resolve_abs_paths( v, host, user, pw, auto_pw_request) new_env[k] = v_value if is_abs_path: abs_paths.append(('ENV', "%s=%s" % (k, v), "%s=%s" % (k, v_value))) if not found and package: not_found_packages.append(package) env_command = "env " + ' '.join( ["%s=%s" % (k, v) for (k, v) in new_env.items()]) except nm.AuthenticationRequest as e: raise nm.InteractionNeededError( e, cls.runNode, (node, launch_config, force2host, masteruri, auto_pw_request)) startcmd = [ env_command, nm.settings().start_remote_script, '--package', str(n.package), '--node_type', str(n.type), '--node_name', str(node), '--node_respawn true' if n.respawn else '' ] if not masteruri is None: startcmd.append('--masteruri') startcmd.append(masteruri) if prefix: startcmd[len(startcmd):] = ['--prefix', prefix] #rename the absolute paths in the args of the node node_args = [] try: for a in n.args.split(): a_value, is_abs_path, found, package = cls._resolve_abs_paths( a, host, user, pw, auto_pw_request) node_args.append(a_value) if is_abs_path: abs_paths.append(('ARGS', a, a_value)) if not found and package: not_found_packages.append(package) startcmd[len(startcmd):] = node_args startcmd[len(startcmd):] = args rospy.loginfo("Run remote on %s: %s", host, str(' '.join(startcmd))) #'print "RUN CALL", node, time.time() _, stdout, stderr, ok = nm.ssh().ssh_exec(host, startcmd, user, pw, auto_pw_request, close_stdin=True) output = stdout.read() error = stderr.read() stdout.close() stderr.close() #'print "RUN CALLOK", node, time.time() except nm.AuthenticationRequest as e: raise nm.InteractionNeededError( e, cls.runNode, (node, launch_config, force2host, masteruri, auto_pw_request)) if ok: if error: rospy.logwarn("ERROR while start '%s': %s", node, error) raise StartException( str(''.join( ['The host "', host, '" reports:\n', error]))) if output: rospy.loginfo("STDOUT while start '%s': %s", node, output) # inform about absolute paths in parameter value if len(abs_paths) > 0: rospy.loginfo( "Absolute paths found while start:\n%s", str('\n'.join([ ''.join([p, '\n OLD: ', ov, '\n NEW: ', nv]) for p, ov, nv in abs_paths ]))) if len(not_found_packages) > 0: packages = '\n'.join(not_found_packages) raise StartException( str('\n'.join([ 'Some absolute paths are not renamed because following packages are not found on remote host:', packages ])))