def openLog(cls, nodename, host):
   '''
   Opens the log file associated with the given node in a new terminal.
   @param nodename: the name of the node (with name space)
   @type nodename: C{str}
   @param host: the host name or ip where the log file are
   @type host: C{str}
   @return: C{True}, if a log file was found
   @rtype: C{bool}
   @raise Exception: on errors while resolving host
   @see: L{node_manager_fkie.is_local()}
   '''
   title_opt = ' '.join(['"LOG', nodename, 'on', host, '"'])
   if nm.is_local(host):
     found = False
     screenLog = nm.screen().getScreenLogFile(node=nodename)
     if os.path.isfile(screenLog):
       cmd = nm.terminal_cmd([nm.LESS, screenLog], title_opt)
       rospy.loginfo("open log: %s", cmd)
       subprocess.Popen(shlex.split(cmd))
       found = True
     #open roslog file
     roslog = nm.screen().getROSLogFile(nodename)
     if os.path.isfile(roslog):
       title_opt = title_opt.replace('LOG', 'ROSLOG')
       cmd = nm.terminal_cmd([nm.LESS, roslog], title_opt)
       rospy.loginfo("open ROS log: %s", cmd)
       subprocess.Popen(shlex.split(cmd))
       found = True
     return found
   else:
     nm.ssh().ssh_x11_exec(host, [nm.STARTER_SCRIPT, '--show_screen_log', nodename], title_opt)
     nm.ssh().ssh_x11_exec(host, [nm.STARTER_SCRIPT, '--show_ros_log', nodename], title_opt.replace('LOG', 'ROSLOG'))
   return False
 def deleteLog(cls, nodename, host, auto_pw_request=False, user=None, pw=None):
     '''
     Deletes the log file associated with the given node.
     @param nodename: the name of the node (with name space)
     @type nodename: C{str}
     @param host: the host name or ip where the log file are to delete
     @type host: C{str}
     @raise Exception: on errors while resolving host
     @see: L{node_manager_fkie.is_local()}
     '''
     rospy.loginfo("delete log for '%s' on '%s'", utf8(nodename), utf8(host))
     if nm.is_local(host):
         screenLog = nm.screen().getScreenLogFile(node=nodename)
         pidFile = nm.screen().getScreenPidFile(node=nodename)
         roslog = nm.screen().getROSLogFile(nodename)
         if os.path.isfile(screenLog):
             os.remove(screenLog)
         if os.path.isfile(pidFile):
             os.remove(pidFile)
         if os.path.isfile(roslog):
             os.remove(roslog)
     else:
         try:
             # output ignored: output, error, ok
             _, stdout, _, ok = nm.ssh().ssh_exec(host, [nm.settings().start_remote_script, '--delete_logs', nodename], user, pw, auto_pw_request, close_stdin=True, close_stdout=False, close_stderr=True)
             if ok:
                 stdout.readlines()
                 stdout.close()
         except nm.AuthenticationRequest as e:
             raise nm.InteractionNeededError(e, cls.deleteLog, (nodename, host, auto_pw_request))
 def deleteLog(cls, nodename, host, auto_pw_request=False, user=None, pw=None):
     '''
     Deletes the log file associated with the given node.
     @param nodename: the name of the node (with name space)
     @type nodename: C{str}
     @param host: the host name or ip where the log file are to delete
     @type host: C{str}
     @raise Exception: on errors while resolving host
     @see: L{node_manager_fkie.is_local()}
     '''
     rospy.loginfo("delete log for '%s' on '%s'", str(nodename), str(host))
     if nm.is_local(host):
         screenLog = nm.screen().getScreenLogFile(node=nodename)
         pidFile = nm.screen().getScreenPidFile(node=nodename)
         roslog = nm.screen().getROSLogFile(nodename)
         if os.path.isfile(screenLog):
             os.remove(screenLog)
         if os.path.isfile(pidFile):
             os.remove(pidFile)
         if os.path.isfile(roslog):
             os.remove(roslog)
     else:
         try:
             # output ignored: output, error, ok
             nm.ssh().ssh_exec(host, [nm.settings().start_remote_script, '--delete_logs', nodename], user, pw, auto_pw_request, close_stdin=True, close_stdout=True, close_stderr=True)
         except nm.AuthenticationRequest as e:
             raise nm.InteractionNeededError(e, cls.deleteLog, (nodename, host, auto_pw_request))
 def openLog(cls, nodename, host, user=None):
   '''
   Opens the log file associated with the given node in a new terminal.
   @param nodename: the name of the node (with name space)
   @type nodename: C{str}
   @param host: the host name or ip where the log file are
   @type host: C{str}
   @return: C{True}, if a log file was found
   @rtype: C{bool}
   @raise Exception: on errors while resolving host
   @see: L{node_manager_fkie.is_local()}
   '''
   rospy.loginfo("show log for '%s' on '%s'", str(nodename), str(host))
   title_opt = 'LOG %s on %s'%(nodename, host)
   if nm.is_local(host):
     found = False
     screenLog = nm.screen().getScreenLogFile(node=nodename)
     if os.path.isfile(screenLog):
       cmd = nm.settings().terminal_cmd([nm.settings().log_viewer, screenLog], title_opt)
       rospy.loginfo("open log: %s", cmd)
       SupervisedPopen(shlex.split(cmd), id="Open log", description="Open log for '%s' on '%s'"%(str(nodename), str(host)))
       found = True
     #open roslog file
     roslog = nm.screen().getROSLogFile(nodename)
     if os.path.isfile(roslog):
       title_opt = title_opt.replace('LOG', 'ROSLOG')
       cmd = nm.settings().terminal_cmd([nm.settings().log_viewer, roslog], title_opt)
       rospy.loginfo("open ROS log: %s", cmd)
       SupervisedPopen(shlex.split(cmd), id="Open log", description="Open log for '%s' on '%s'"%(str(nodename), str(host)))
       found = True
     return found
   else:
     ps = nm.ssh().ssh_x11_exec(host, [nm.settings().start_remote_script, '--show_screen_log', nodename], title_opt, user)
     ps = nm.ssh().ssh_x11_exec(host, [nm.settings().start_remote_script, '--show_ros_log', nodename], title_opt.replace('LOG', 'ROSLOG'), user)
   return False
Example #5
0
 def copylogPath2Clipboards(self,
                            host,
                            nodes=[],
                            auto_pw_request=True,
                            user=None,
                            pw=None):
     if nm.is_local(host):
         if len(nodes) == 1:
             return nm.screen().getScreenLogFile(node=nodes[0])
         else:
             return nm.screen().LOG_PATH
     else:
         request = '[]' if len(nodes) != 1 else nodes[0]
         try:
             output, error, ok = nm.ssh().ssh_exec(
                 host, [nm.STARTER_SCRIPT, '--ros_log_path', request], user,
                 pw, auto_pw_request)
             if ok:
                 return output
             else:
                 raise StartException(
                     str(''.join([
                         'Get log path from "', host, '" failed:\n', error
                     ])))
         except nm.AuthenticationRequest as e:
             raise nm.InteractionNeededError(
                 e, cls.deleteLog, (nodename, host, auto_pw_request))
 def deleteLog(cls, nodename, host):
     '''
 Deletes the log file associated with the given node.
 @param nodename: the name of the node (with name space)
 @type nodename: C{str}
 @param host: the host name or ip where the log file are to delete
 @type host: C{str}
 @raise Exception: on errors while resolving host
 @see: L{node_manager_fkie.is_local()}
 '''
     if nm.is_local(host):
         screenLog = nm.screen().getScreenLogFile(node=nodename)
         pidFile = nm.screen().getScreenPidFile(node=nodename)
         roslog = nm.screen().getROSLogFile(nodename)
         if os.path.isfile(screenLog):
             os.remove(screenLog)
         if os.path.isfile(pidFile):
             os.remove(pidFile)
         if os.path.isfile(roslog):
             os.remove(roslog)
     else:
         (stdin, stdout, stderr), ok = nm.ssh().ssh_exec(
             host, [nm.STARTER_SCRIPT, '--delete_logs', nodename])
         if ok:
             stdin.close()
Example #7
0
 def openLog(cls, nodename, host):
     '''
 Opens the log file associated with the given node in a new terminal.
 @param nodename: the name of the node (with name space)
 @type nodename: C{str}
 @param host: the host name or ip where the log file are
 @type host: C{str}
 @return: C{True}, if a log file was found
 @rtype: C{bool}
 @raise Exception: on errors while resolving host
 @see: L{node_manager_fkie.is_local()}
 '''
     rospy.loginfo("show log for '%s' on '%s'", str(nodename), str(host))
     title_opt = ' '.join(['"LOG', nodename, 'on', host, '"'])
     if nm.is_local(host):
         found = False
         screenLog = nm.screen().getScreenLogFile(node=nodename)
         if os.path.isfile(screenLog):
             cmd = nm.terminal_cmd([nm.LESS, screenLog], title_opt)
             rospy.loginfo("open log: %s", cmd)
             ps = subprocess.Popen(shlex.split(cmd))
             # wait for process to avoid 'defunct' processes
             thread = threading.Thread(target=ps.wait)
             thread.setDaemon(True)
             thread.start()
             found = True
         #open roslog file
         roslog = nm.screen().getROSLogFile(nodename)
         if os.path.isfile(roslog):
             title_opt = title_opt.replace('LOG', 'ROSLOG')
             cmd = nm.terminal_cmd([nm.LESS, roslog], title_opt)
             rospy.loginfo("open ROS log: %s", cmd)
             ps = subprocess.Popen(shlex.split(cmd))
             # wait for process to avoid 'defunct' processes
             thread = threading.Thread(target=ps.wait)
             thread.setDaemon(True)
             thread.start()
             found = True
         return found
     else:
         ps = nm.ssh().ssh_x11_exec(
             host, [nm.STARTER_SCRIPT, '--show_screen_log', nodename],
             title_opt)
         # wait for process to avoid 'defunct' processes
         thread = threading.Thread(target=ps.wait)
         thread.setDaemon(True)
         thread.start()
         ps = nm.ssh().ssh_x11_exec(
             host, [nm.STARTER_SCRIPT, '--show_ros_log', nodename],
             title_opt.replace('LOG', 'ROSLOG'))
         # wait for process to avoid 'defunct' processes
         thread = threading.Thread(target=ps.wait)
         thread.setDaemon(True)
         thread.start()
     return False
 def openLog(cls, nodename, host, user=None):
   '''
   Opens the log file associated with the given node in a new terminal.
   @param nodename: the name of the node (with name space)
   @type nodename: C{str}
   @param host: the host name or ip where the log file are
   @type host: C{str}
   @return: C{True}, if a log file was found
   @rtype: C{bool}
   @raise Exception: on errors while resolving host
   @see: L{node_manager_fkie.is_local()}
   '''
   rospy.loginfo("show log for '%s' on '%s'", str(nodename), str(host))
   title_opt = ' '.join(['"LOG', nodename, 'on', host, '"'])
   if nm.is_local(host):
     found = False
     screenLog = nm.screen().getScreenLogFile(node=nodename)
     if os.path.isfile(screenLog):
       cmd = nm.terminal_cmd([nm.LESS, screenLog], title_opt)
       rospy.loginfo("open log: %s", cmd)
       ps = subprocess.Popen(shlex.split(cmd))
       # wait for process to avoid 'defunct' processes
       thread = threading.Thread(target=ps.wait)
       thread.setDaemon(True)
       thread.start()
       found = True
     #open roslog file
     roslog = nm.screen().getROSLogFile(nodename)
     if os.path.isfile(roslog):
       title_opt = title_opt.replace('LOG', 'ROSLOG')
       cmd = nm.terminal_cmd([nm.LESS, roslog], title_opt)
       rospy.loginfo("open ROS log: %s", cmd)
       ps = subprocess.Popen(shlex.split(cmd))
       # wait for process to avoid 'defunct' processes
       thread = threading.Thread(target=ps.wait)
       thread.setDaemon(True)
       thread.start()
       found = True
     return found
   else:
     ps = nm.ssh().ssh_x11_exec(host, [nm.STARTER_SCRIPT, '--show_screen_log', nodename], title_opt, user)
     # wait for process to avoid 'defunct' processes
     thread = threading.Thread(target=ps.wait)
     thread.setDaemon(True)
     thread.start()
     ps = nm.ssh().ssh_x11_exec(host, [nm.STARTER_SCRIPT, '--show_ros_log', nodename], title_opt.replace('LOG', 'ROSLOG'), user)
     # wait for process to avoid 'defunct' processes
     thread = threading.Thread(target=ps.wait)
     thread.setDaemon(True)
     thread.start()
   return False
Example #9
0
 def openLog(cls, nodename, host, user=None):
     '''
 Opens the log file associated with the given node in a new terminal.
 @param nodename: the name of the node (with name space)
 @type nodename: C{str}
 @param host: the host name or ip where the log file are
 @type host: C{str}
 @return: C{True}, if a log file was found
 @rtype: C{bool}
 @raise Exception: on errors while resolving host
 @see: L{node_manager_fkie.is_local()}
 '''
     rospy.loginfo("show log for '%s' on '%s'", str(nodename), str(host))
     title_opt = 'LOG %s on %s' % (nodename, host)
     if nm.is_local(host):
         found = False
         screenLog = nm.screen().getScreenLogFile(node=nodename)
         if os.path.isfile(screenLog):
             cmd = nm.settings().terminal_cmd(
                 [nm.settings().log_viewer, screenLog], title_opt)
             rospy.loginfo("open log: %s", cmd)
             SupervisedPopen(shlex.split(cmd),
                             id="Open log",
                             description="Open log for '%s' on '%s'" %
                             (str(nodename), str(host)))
             found = True
         #open roslog file
         roslog = nm.screen().getROSLogFile(nodename)
         if os.path.isfile(roslog):
             title_opt = title_opt.replace('LOG', 'ROSLOG')
             cmd = nm.settings().terminal_cmd(
                 [nm.settings().log_viewer, roslog], title_opt)
             rospy.loginfo("open ROS log: %s", cmd)
             SupervisedPopen(shlex.split(cmd),
                             id="Open log",
                             description="Open log for '%s' on '%s'" %
                             (str(nodename), str(host)))
             found = True
         return found
     else:
         ps = nm.ssh().ssh_x11_exec(host, [
             nm.settings().start_remote_script, '--show_screen_log',
             nodename
         ], title_opt, user)
         ps = nm.ssh().ssh_x11_exec(host, [
             nm.settings().start_remote_script, '--show_ros_log', nodename
         ], title_opt.replace('LOG', 'ROSLOG'), user)
     return False
Example #10
0
  def accept(self):
    if self.textedit.isVisible():
      try:
        tmp_file = os.path.join(nm.screen().LOG_PATH, 'tmp_sync_interface.sync')
        with open(tmp_file, 'w+') as f: 
          iface = f.write(self.textedit.toPlainText())
        from master_sync_fkie.common import read_interface
        read_interface(tmp_file)
        if not self._new_iface and self._interfaces_files.has_key(self.interface_field.currentText()):
          fileName = self._interfaces_files[self.interface_field.currentText()]
        else:
          fileName, selectedFilter = QtGui.QFileDialog.getSaveFileName(self, 'Save sync interface', '/home', "Sync Files (*.sync)")
        if fileName:
          with open(fileName, 'w+') as f: 
            iface = f.write(self.textedit.toPlainText())
            if self._new_iface:
              self.interface_field.clear()
              self._interfaces_files = None
            self._on_select_interface_clicked()
#        QtGui.QDialog.accept(self)
#        self.resetView()
      except Exception as e:
        WarningMessageBox(QtGui.QMessageBox.Warning, "Create sync interface", 
                          "Error while create interface",
                          str(e)).exec_()
    elif self.interface_field.isVisible():
      interface = self.interface_field.currentText()
      if self._interfaces_files and self._interfaces_files.has_key(interface):
        self._sync_args = []
        self._sync_args.append(''.join(['_interface_url:=', interface]))
        QtGui.QDialog.accept(self)
        self.resetView()
    else:
      QtGui.QDialog.accept(self)
      self.resetView()
Example #11
0
 def copylogPath2Clipboards(self, host, nodes=[], auto_pw_request=True, user=None, pw=None):
   if nm.is_local(host):
     if len(nodes) == 1:
       return nm.screen().getScreenLogFile(node=nodes[0])
     else:
       return nm.screen().LOG_PATH
   else:
     request = '[]' if len(nodes) != 1 else nodes[0]
     try:
       output, error, ok = nm.ssh().ssh_exec(host, [nm.STARTER_SCRIPT, '--ros_log_path', request], user, pw, auto_pw_request)
       if ok:
         return output
       else:
         raise StartException(str(''.join(['Get log path from "', host, '" failed:\n', error])))
     except nm.AuthenticationRequest as e:
       raise nm.InteractionNeededError(e, cls.deleteLog, (nodename, host, auto_pw_request))
Example #12
0
 def copylogPath2Clipboards(cls, host, nodes=[], auto_pw_request=False, user=None, pw=None):
   if nm.is_local(host):
     if len(nodes) == 1:
       return nm.screen().getScreenLogFile(node=nodes[0])
     else:
       return nm.screen().LOG_PATH
   else:
     request = '[]' if len(nodes) != 1 else nodes[0]
     try:
       socket.setdefaulttimeout(3)
       output, error, ok = nm.ssh().ssh_exec(host, [nm.settings().start_remote_script, '--ros_log_path', request], user, pw, auto_pw_request)
       if ok:
         return output
       else:
         raise StartException(str(''.join(['Get log path from "', host, '" failed:\n', error])))
     except nm.AuthenticationRequest as e:
       raise nm.InteractionNeededError(e, cls.copylogPath2Clipboards, (host, nodes, auto_pw_request))
     finally:
       socket.setdefaulttimeout(None)
 def get_log_path(cls, host, nodes=[], auto_pw_request=False, user=None, pw=None):
     if nm.is_local(host):
         if len(nodes) == 1:
             return nm.screen().getScreenLogFile(node=nodes[0])
         else:
             return nm.screen().LOG_PATH
     else:
         request = '[]' if len(nodes) != 1 else nodes[0]
         try:
             socket.setdefaulttimeout(3)
             _, stdout, _, ok = nm.ssh().ssh_exec(host, [nm.settings().start_remote_script, '--ros_log_path', request], user, pw, auto_pw_request, close_stdin=True, close_stderr=True)
             if ok:
                 output = stdout.read()
                 stdout.close()
                 return output.strip()
             else:
                 raise StartException(utf8(''.join(['Get log path from "', host, '" failed'])))
         except nm.AuthenticationRequest as e:
             raise nm.InteractionNeededError(e, cls.get_log_path, (host, nodes, auto_pw_request))
         finally:
             socket.setdefaulttimeout(None)
 def get_log_path(cls, host, nodes=[], auto_pw_request=False, user=None, pw=None):
     if nm.is_local(host):
         if len(nodes) == 1:
             return nm.screen().getScreenLogFile(node=nodes[0])
         else:
             return nm.screen().LOG_PATH
     else:
         request = '[]' if len(nodes) != 1 else nodes[0]
         try:
             socket.setdefaulttimeout(3)
             _, stdout, _, ok = nm.ssh().ssh_exec(host, [nm.settings().start_remote_script, '--ros_log_path', request], user, pw, auto_pw_request, close_stdin=True, close_stderr=True)
             if ok:
                 output = stdout.read()
                 stdout.close()
                 return output.strip()
             else:
                 raise StartException(str(''.join(['Get log path from "', host, '" failed'])))
         except nm.AuthenticationRequest as e:
             raise nm.InteractionNeededError(e, cls.get_log_path, (host, nodes, auto_pw_request))
         finally:
             socket.setdefaulttimeout(None)
 def deleteLog(cls, nodename, host):
   '''
   Deletes the log file associated with the given node.
   @param nodename: the name of the node (with name space)
   @type nodename: C{str}
   @param host: the host name or ip where the log file are to delete
   @type host: C{str}
   @raise Exception: on errors while resolving host
   @see: L{node_manager_fkie.is_local()}
   '''
   if nm.is_local(host):
     screenLog = nm.screen().getScreenLogFile(node=nodename)
     pidFile = nm.screen().getScreenPidFile(node=nodename)
     roslog = nm.screen().getROSLogFile(nodename)
     if os.path.isfile(screenLog):
       os.remove(screenLog)
     if os.path.isfile(pidFile):
       os.remove(pidFile)
     if os.path.isfile(roslog):
       os.remove(roslog)
   else:
     (stdin, stdout, stderr), ok = nm.ssh().ssh_exec(host, [nm.STARTER_SCRIPT, '--delete_logs', nodename])
     if ok:
       stdin.close()
Example #16
0
    def accept(self):
        if self.textedit.isVisible():
            try:
                tmp_file = os.path.join(nm.screen().LOG_PATH,
                                        'tmp_sync_interface.sync')
                with open(tmp_file, 'w+') as f:
                    f.write(self.textedit.toPlainText())
                from master_discovery_fkie.common import read_interface
                read_interface(tmp_file)
                if not self._new_iface and self._interfaces_files.has_key(
                        self.interface_field.currentText()):
                    fileName = self._interfaces_files[
                        self.interface_field.currentText()]
                else:
                    fileName, _ = QtGui.QFileDialog.getSaveFileName(
                        self, 'Save sync interface', '/home',
                        "Sync Files (*.sync)")
                if fileName:
                    with open(fileName, 'w+') as f:
                        self._interface_filename = fileName
                        f.write(self.textedit.toPlainText())
                        if self._new_iface:
                            self.interface_field.clear()
                            self._interfaces_files = None
                        self._on_select_interface_clicked()


#        QtGui.QDialog.accept(self)
#        self.resetView()
            except Exception as e:
                WarningMessageBox(QtGui.QMessageBox.Warning,
                                  "Create sync interface",
                                  "Error while create interface",
                                  str(e)).exec_()
        elif self.interface_field.isVisible():
            interface = self.interface_field.currentText()
            if self._interfaces_files and self._interfaces_files.has_key(
                    interface):
                self._interface_filename = self._interfaces_files[interface]
                self._sync_args = []
                self._sync_args.append(''.join(['_interface_url:=',
                                                interface]))
                QtGui.QDialog.accept(self)
                self.resetView()
        else:
            QtGui.QDialog.accept(self)
            self.resetView()
    def accept(self):
        if self.textedit.isVisible():
            try:
                tmp_file = os.path.join(nm.screen().LOG_PATH, 'tmp_sync_interface.sync')
                with open(tmp_file, 'w+') as f:
                    f.write(self.textedit.toPlainText())
                from master_discovery_fkie.common import read_interface
                read_interface(tmp_file)
                if not self._new_iface and self.interface_field.currentText() in self._interfaces_files:
                    fileName = self._interfaces_files[self.interface_field.currentText()]
                else:
                    fileName, _ = QFileDialog.getSaveFileName(self, 'Save sync interface', '/home', "Sync Files (*.sync)")
                if fileName:
                    with open(fileName, 'w+') as f:
                        self._interface_filename = fileName
                        f.write(self.textedit.toPlainText())
                        if self._new_iface:
                            self.interface_field.clear()
                            self._interfaces_files = None
                        self._on_select_interface_clicked()
#        QDialog.accept(self)
#        self.resetView()
            except Exception as e:
                MessageBox.warning(self, "Create sync interface",
                                   "Error while create interface",
                                   utf8(e))
        elif self.interface_field.isVisible():
            interface = self.interface_field.currentText()
            if self._interfaces_files and interface in self._interfaces_files:
                self._interface_filename = self._interfaces_files[interface]
                self._sync_args = []
                self._sync_args.append(''.join(['_interface_url:=', interface]))
                QDialog.accept(self)
                self.resetView()
        else:
            QDialog.accept(self)
            self.resetView()
    def runNodeWithoutConfig(cls, host, package, binary, name, args=[], masteruri=None, auto_pw_request=False, user=None, pw=None):
        '''
        Start a node with using a launch configuration.
        @param host: the host or ip to run the node
        @type host: C{str}
        @param package: the ROS package containing the binary
        @type package: C{str}
        @param binary: the binary of the node to execute
        @type binary: C{str}
        @param name: the ROS name of the node (with name space)
        @type name: C{str}
        @param args: the list with arguments passed to the binary
        @type args: C{[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 Exception: on errors while resolving host
        @see: L{node_manager_fkie.is_local()}
        '''
        # create the name with namespace
        args2 = list(args)
        fullname = roslib.names.ns_join(roslib.names.SEP, name)
        namespace = ''
        for a in args:
            if a.startswith('__ns:='):
                namespace = a.replace('__ns:=', '')
                fullname = roslib.names.ns_join(namespace, name)
        args2.append(''.join(['__name:=', name]))
        # run on local host
        if nm.is_local(host, wait=True):
            try:
                cmd = roslib.packages.find_node(package, binary)
            except roslib.packages.ROSPkgException as e:
                # multiple nodes, invalid package
                raise StartException(utf8(e))
            # handle different result types str or array of string
#      import types
            if isinstance(cmd, types.StringTypes):
                cmd = [cmd]
            cmd_type = ''
            if cmd is None or len(cmd) == 0:
                raise StartException('%s in package [%s] not found!' % (binary, package))
            if len(cmd) > 1:
                # Open selection for executables
                err = [''.join(['Multiple executables with same name in package [', package, ']  found:'])]
                err.extend(cmd)
                raise StartException('\n'.join(err))
            else:
                cmd_type = cmd[0]
            cmd_str = utf8(' '.join([nm.screen().getSceenCmd(fullname), cmd_type, ' '.join(args2)]))
            rospy.loginfo("Run without config: %s", cmd_str)
            new_env = dict(os.environ)
            if namespace:
                new_env['ROS_NAMESPACE'] = namespace
            if masteruri is not None:
                cls._prepareROSMaster(masteruri)
                new_env['ROS_MASTER_URI'] = masteruri
                ros_hostname = NameResolution.get_ros_hostname(masteruri)
                if ros_hostname:
                    new_env['ROS_HOSTNAME'] = ros_hostname
            SupervisedPopen(shlex.split(cmd_str), env=new_env, object_id="Run without config", description="Run without config [%s]%s" % (utf8(package), utf8(binary)))
        else:
            # run on a remote machine
            startcmd = [nm.settings().start_remote_script,
                        '--package', utf8(package),
                        '--node_type', utf8(binary),
                        '--node_name', utf8(fullname)]
            startcmd[len(startcmd):] = args2
            if masteruri is not None:
                startcmd.append('--masteruri')
                startcmd.append(masteruri)
            rospy.loginfo("Run remote on %s: %s", host, ' '.join(startcmd))
            try:
                _, stdout, stderr, ok = nm.ssh().ssh_exec(host, startcmd, user, pw, auto_pw_request, close_stdin=True)
                if ok:
                    output = stdout.read()
                    error = stderr.read()
                    stdout.close()
                    stderr.close()
                    if error:
                        rospy.logwarn("ERROR while start '%s': %s", name, error)
                        raise StartException(''.join(['The host "', host, '" reports:\n', error]))
                    if output:
                        rospy.logdebug("STDOUT while start '%s': %s", name, output)
                else:
                    if error:
                        rospy.logwarn("ERROR while start '%s': %s", name, error)
                        raise StartException(''.join(['The host "', host, '" reports:\n', error]))
            except nm.AuthenticationRequest as e:
                raise nm.InteractionNeededError(e, cls.runNodeWithoutConfig, (host, package, binary, name, args, masteruri, auto_pw_request))
  def runNode(cls, node, launch_config, force2host=None, masteruri=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} 
    @raise StartException: if the screen is not available on host.
    @raise Exception: on errors while resolving host
    @see: L{node_manager_fkie.is_local()}
    '''
    n = launch_config.getNode(node)
    if n is None:
      raise StartException(''.join(["Node '", node, "' not found!"]))
    
    env = list(n.env_args)
    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]), ''.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]
      host = machine.address
      #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

    if masteruri is None:
      masteruri = nm.nameres().masteruri(n.machine_name)
    # set the ROS_MASTER_URI
    if masteruri is None:
      masteruri = nm.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(global_node_names))
      abs_paths[len(abs_paths):], not_found_packages[len(not_found_packages):] = cls._load_parameters(masteruri, global_node_names, [])
      launch_config.global_param_done.append(masteruri)

    # add params
    if not masteruri is None:
      nodens = ''.join([n.namespace, n.name, '/'])
      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(param)
      rospy.loginfo("Register parameter:\n%s", '\n'.join(params))
      abs_paths[len(abs_paths):], not_found_packages[len(not_found_packages):] = cls._load_parameters(masteruri, params, clear_params)
    if nm.is_local(host): 
      nm.screen().testScreen()
      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
      import types
      if isinstance(cmd, types.StringTypes):
        cmd = [cmd]
      cmd_type = ''
      if cmd is None or len(cmd) == 0:
        raise nm.StartException(' '.join([n.type, 'in package [', n.package, '] not found!\n\nThe package was created?\nIs the binary executable?\n']))
      if len(cmd) > 1:
        # Open selection for executables
        try:
          from PySide 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 nm.StartException('Multiple executables with same name in package found!')
      else:
        cmd_type = cmd[0]
      # determine the current working path, Default: the package of the node
      cwd = nm.get_ros_home()
      if not (n.cwd is None):
        if n.cwd == 'ROS_HOME':
          cwd = nm.get_ros_home()
        elif n.cwd == 'node':
          cwd = os.path.dirname(cmd_type)
#      else:
#        cwd = LaunchConfig.packageName(os.path.dirname(cmd_type))
      cls._prepareROSMaster(masteruri)
      node_cmd = [nm.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))
      if not masteruri is None:
        new_env=dict(os.environ)
        new_env['ROS_MASTER_URI'] = masteruri
        ps = subprocess.Popen(shlex.split(str(' '.join(cmd_args))), cwd=cwd, env=new_env)
      else:
        ps = subprocess.Popen(shlex.split(str(' '.join(cmd_args))), cwd=cwd)
      # wait for process to avoid 'defunct' processes
      thread = threading.Thread(target=ps.wait)
      thread.setDaemon(True)
      thread.start()
    else:
      # 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 nm.StartException("env_loader in machine tag currently not supported")
      if env:
        env_command = "env "+' '.join(["%s=%s"%(k,v) for (k, v) in env])
      
      startcmd = [env_command, nm.STARTER_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 = []
      for a in n.args.split():
        a_value, is_abs_path, found, package = cls._resolve_abs_paths(a, host)
        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)))
      (stdin, stdout, stderr), ok = nm.ssh().ssh_exec(host, startcmd)

      if ok:
        stdin.close()
  #      stderr.close()
  #      stdout.close()
        error = stderr.read()
        if error:
          rospy.logwarn("ERROR while start '%s': %s", node, error)
          raise nm.StartException(str(''.join(['The host "', host, '" reports:\n', error])))
        output = stdout.read()
        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 nm.StartException(str('\n'.join(['Some absolute paths are not renamed because following packages are not found on remote host:', packages])))
 def runNodeWithoutConfig(cls, host, package, type, name, args=[], masteruri=None):
   '''
   Start a node with using a launch configuration.
   @param host: the host or ip to run the node
   @type host: C{str} 
   @param package: the ROS package containing the binary
   @type package: C{str} 
   @param type: the binary of the node to execute
   @type type: C{str} 
   @param name: the ROS name of the node (with name space)
   @type name: C{str} 
   @param args: the list with arguments passed to the binary
   @type args: C{[str, ...]} 
   @raise Exception: on errors while resolving host
   @see: L{node_manager_fkie.is_local()}
   '''
   # create the name with namespace
   args2 = list(args)
   fullname = roslib.names.ns_join(roslib.names.SEP, name)
   for a in args:
     if a.startswith('__ns:='):
       fullname = roslib.names.ns_join(a.replace('__ns:=', ''), name)
   args2.append(''.join(['__name:=', name]))
   # run on local host
   if nm.is_local(host):
     try:
       cmd = roslib.packages.find_node(package, type)
     except roslib.packages.ROSPkgException as e:
       # multiple nodes, invalid package
       raise StartException(str(e))
     # handle diferent result types str or array of string
     import types
     if isinstance(cmd, types.StringTypes):
       cmd = [cmd]
     cmd_type = ''
     if cmd is None or len(cmd) == 0:
       raise nm.StartException(' '.join([type, 'in package [', package, '] not found!']))
     if len(cmd) > 1:
       # Open selection for executables
       try:
         from PySide import QtGui
         item, result = QtGui.QInputDialog.getItem(None, ' '.join(['Multiple executables', type, 'in', package]),
                                           'Select an executable',
                                           cmd, 0, False)
         if result:
           #open the selected screen
           cmd_type = item
         else:
           return
       except:
         raise nm.StartException('Multiple executables with same name in package found!')
     else:
       cmd_type = cmd[0]
     cmd_str = str(' '.join([nm.screen().getSceenCmd(fullname), cmd_type, ' '.join(args2)]))
     rospy.loginfo("Run without config: %s", cmd_str)
     ps = None
     if not masteruri is None:
       cls._prepareROSMaster(masteruri)
       new_env=dict(os.environ)
       new_env['ROS_MASTER_URI'] = masteruri
       ps = subprocess.Popen(shlex.split(cmd_str), env=new_env)
     else:
       ps = subprocess.Popen(shlex.split(cmd_str))
     # wait for process to avoid 'defunct' processes
     thread = threading.Thread(target=ps.wait)
     thread.setDaemon(True)
     thread.start()
   else:
     # run on a remote machine
     startcmd = [nm.STARTER_SCRIPT, 
                 '--package', str(package),
                 '--node_type', str(type),
                 '--node_name', str(fullname)]
     startcmd[len(startcmd):] = args2
     if not masteruri is None:
       startcmd.append('--masteruri')
       startcmd.append(masteruri)
     rospy.loginfo("Run remote on %s: %s", host, ' '.join(startcmd))
     (stdin, stdout, stderr), ok = nm.ssh().ssh_exec(host, startcmd)
     if ok:
       stdin.close()
       error = stderr.read()
       if error:
         rospy.logwarn("ERROR while start '%s': %s", name, error)
         from PySide import QtGui
         QtGui.QMessageBox.warning(None, 'Error while remote start %s'%str(name),
                                     str(''.join(['The host "', host, '" reports:\n', error])),
                                     QtGui.QMessageBox.Ok)
       output = stdout.read()
       if output:
         rospy.logdebug("STDOUT while start '%s': %s", name, output)
     else:
       if stderr:
         rospy.logwarn("ERROR while start '%s': %s", name, stderr)
         from PySide import QtGui
         QtGui.QMessageBox.warning(None, 'Error while remote start %s'%str(name),
                                     str(''.join(['The host "', host, '" reports:\n', stderr])),
                                     QtGui.QMessageBox.Ok)
Example #21
0
    def runNode(cls,
                node,
                launch_config,
                force2host=None,
                masteruri=None,
                auto_pw_request=False,
                user=None,
                pw=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} 
    @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)
        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]), ''.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]
            host = machine.address
            #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

        if masteruri is None:
            masteruri = nm.nameres().masteruri(n.machine_name)
        # set the ROS_MASTER_URI
        if masteruri is None:
            masteruri = nm.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(global_node_names))
            abs_paths[len(abs_paths):], not_found_packages[
                len(not_found_packages):] = cls._load_parameters(
                    masteruri, global_node_names, [])
            launch_config.global_param_done.append(masteruri)

        # add params
        if not masteruri is None:
            nodens = ''.join([n.namespace, n.name, '/'])
            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(param)
            rospy.loginfo("Register parameter:\n%s", '\n'.join(params))
            abs_paths[len(abs_paths):], not_found_packages[
                len(not_found_packages):] = cls._load_parameters(
                    masteruri, params, clear_params)
        #'print "RUN prepared", node, time.time()

        if nm.is_local(host):
            nm.screen().testScreen()
            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
            import types
            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:
                # Open selection for executables
                try:
                    from PySide 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:
                cmd_type = cmd[0]
            # determine the current working path, Default: the package of the node
            cwd = nm.get_ros_home()
            if not (n.cwd is None):
                if n.cwd == 'ROS_HOME':
                    cwd = nm.get_ros_home()
                elif n.cwd == 'node':
                    cwd = os.path.dirname(cmd_type)
#      else:
#        cwd = LaunchConfig.packageName(os.path.dirname(cmd_type))
            cls._prepareROSMaster(masteruri)
            node_cmd = [
                nm.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))
            if not masteruri is None:
                new_env = dict(os.environ)
                new_env['ROS_MASTER_URI'] = masteruri
                ps = subprocess.Popen(shlex.split(str(' '.join(cmd_args))),
                                      cwd=cwd,
                                      env=new_env)
            else:
                ps = subprocess.Popen(shlex.split(str(' '.join(cmd_args))),
                                      cwd=cwd)
            # wait for process to avoid 'defunct' processes
            thread = threading.Thread(target=ps.wait)
            thread.setDaemon(True)
            thread.start()
        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:
                env_command = "env " + ' '.join(
                    ["%s=%s" % (k, v) for (k, v) in env])

            startcmd = [
                env_command, nm.STARTER_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)
                    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()
                output, error, ok = nm.ssh().ssh_exec(host, startcmd, user, pw,
                                                      auto_pw_request)
                #'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
                    ])))
Example #22
0
  def runNode(cls, node, launch_config):
    '''
    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} 
    @raise StartException: if the screen is not available on host.
    @raise Exception: on errors while resolving host
    @see: L{node_manager_fkie.is_local()}
    '''
    n = launch_config.getNode(node)
    if n is None:
      raise StartException(''.join(["Node '", node, "' not found!"]))
    
    env = list(n.env_args)
    prefix = n.launch_prefix if not n.launch_prefix is None else ''
    # thus the parameters while the transfer are not separated
    if prefix:
      prefix = ''.join(['"', prefix, '"'])
    args = [''.join(['__ns:=', n.namespace]), ''.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]
      host = machine.address
      #TODO: env-loader support?
#      if hasattr(machine, "env_loader") and machine.env_loader:
#        env_loader = machine.env_loader

    masteruri = nm.nameres().getUri(host=host)
    # set the ROS_MASTER_URI
    if masteruri is None:
      env.append(('ROS_MASTER_URI', nm.masteruri_from_ros()))

    # 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(global_node_names))
      cls._load_parameters(masteruri, global_node_names, [])
      launch_config.global_param_done.append(masteruri)

    # add params
    if not masteruri is None:
      nodens = ''.join([n.namespace, n.name, '/'])
      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(param)
      rospy.loginfo("Register parameter:\n%s", '\n'.join(params))
      cls._load_parameters(masteruri, params, clear_params)
    if nm.is_local(host): 
      nm.screen().testScreen()
      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
      import types
      if isinstance(cmd, types.StringTypes):
        cmd = [cmd]
      cmd_type = ''
      if cmd is None or len(cmd) == 0:
        raise nm.StartException(' '.join([n.type, 'in package [', n.package, '] not found!\n\nThe package was created?\nIs the binary executable?\n']))
      if len(cmd) > 1:
        # Open selection for executables
        try:
          from PySide 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 nm.StartException('Multiple executables with same name in package found!')
      else:
        cmd_type = cmd[0]
      node_cmd = [prefix, cmd_type]
      cmd_args = [nm.screen().getSceenCmd(node)]
      cmd_args[len(cmd_args):] = node_cmd
      cmd_args.append(n.args)
      cmd_args[len(cmd_args):] = args
      rospy.loginfo("RUN: %s", ' '.join(cmd_args))
      subprocess.Popen(shlex.split(str(' '.join(cmd_args))))
    else:
      # start remote
      if launch_config.PackageName is None:
        raise StartException(''.join(["Can't run remote without a valid package name!"]))
      # setup environment
      env_command = ''
      if env_loader:
        rospy.logwarn("env_loader in machine tag currently not supported")
        raise nm.StartException("env_loader in machine tag currently not supported")
      if env:
        env_command = "env "+' '.join(["%s=%s"%(k,v) for (k, v) in env])
      
      startcmd = [env_command, nm.STARTER_SCRIPT, 
                  '--package', str(n.package),
                  '--node_type', str(n.type),
                  '--node_name', str(node)]
      if prefix:
        startcmd[len(startcmd):] = ['--prefix', prefix]

      startcmd[len(startcmd):] = n.args
      startcmd[len(startcmd):] = args
      rospy.loginfo("Run remote: %s", ' '.join(startcmd))
      (stdin, stdout, stderr), ok = nm.ssh().ssh_exec(host, startcmd)

      if ok:
        stdin.close()
  #      stderr.close()
  #      stdout.close()
        error = stderr.read()
        if error:
          rospy.logwarn("ERROR while start '%s': %s", node, error)
          raise nm.StartException(str(''.join(['The host "', host, '" reports:\n', error])))
        output = stdout.read()
        if output:
          rospy.logdebug("STDOUT while start '%s': %s", node, output)
Example #23
0
    def runNodeWithoutConfig(cls,
                             host,
                             package,
                             binary,
                             name,
                             args=[],
                             masteruri=None,
                             auto_pw_request=False,
                             user=None,
                             pw=None):
        '''
    Start a node with using a launch configuration.
    @param host: the host or ip to run the node
    @type host: C{str} 
    @param package: the ROS package containing the binary
    @type package: C{str} 
    @param binary: the binary of the node to execute
    @type binary: C{str} 
    @param name: the ROS name of the node (with name space)
    @type name: C{str} 
    @param args: the list with arguments passed to the binary
    @type args: C{[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 Exception: on errors while resolving host
    @see: L{node_manager_fkie.is_local()}
    '''
        # create the name with namespace
        args2 = list(args)
        fullname = roslib.names.ns_join(roslib.names.SEP, name)
        namespace = ''
        for a in args:
            if a.startswith('__ns:='):
                namespace = a.replace('__ns:=', '')
                fullname = roslib.names.ns_join(namespace, name)
        args2.append(''.join(['__name:=', name]))
        # run on local host
        if nm.is_local(host):
            try:
                cmd = roslib.packages.find_node(package, binary)
            except roslib.packages.ROSPkgException as e:
                # multiple nodes, invalid package
                raise StartException(str(e))
            # handle different result types str or array of string
#      import types
            if isinstance(cmd, types.StringTypes):
                cmd = [cmd]
            cmd_type = ''
            if cmd is None or len(cmd) == 0:
                raise StartException(' '.join(
                    [binary, 'in package [', package, '] not found!']))
            if len(cmd) > 1:
                # Open selection for executables
                #        try:
                #          from python_qt_binding import QtGui
                #          item, result = QtGui.QInputDialog.getItem(None, ' '.join(['Multiple executables', type, 'in', package]),
                #                                            'Select an executable',
                #                                            cmd, 0, False)
                #          if result:
                #            #open the selected screen
                #            cmd_type = item
                #          else:
                #            return
                #        except:
                err = [
                    ''.join([
                        'Multiple executables with same name in package [',
                        package, ']  found:'
                    ])
                ]
                err.extend(cmd)
                raise StartException('\n'.join(err))
            else:
                cmd_type = cmd[0]
            cmd_str = str(' '.join(
                [nm.screen().getSceenCmd(fullname), cmd_type,
                 ' '.join(args2)]))
            rospy.loginfo("Run without config: %s", cmd_str)
            ps = None
            new_env = dict(os.environ)
            if namespace:
                new_env['ROS_NAMESPACE'] = namespace
            if not masteruri is None:
                cls._prepareROSMaster(masteruri)
                new_env['ROS_MASTER_URI'] = masteruri
            SupervisedPopen(shlex.split(cmd_str),
                            env=new_env,
                            id="Run without config",
                            description="Run without config [%s]%s" %
                            (str(package), str(binary)))
        else:
            # run on a remote machine
            startcmd = [
                nm.settings().start_remote_script, '--package',
                str(package), '--node_type',
                str(binary), '--node_name',
                str(fullname)
            ]
            startcmd[len(startcmd):] = args2
            if not masteruri is None:
                startcmd.append('--masteruri')
                startcmd.append(masteruri)
            rospy.loginfo("Run remote on %s: %s", host, ' '.join(startcmd))
            try:
                _, stdout, stderr, ok = nm.ssh().ssh_exec(host,
                                                          startcmd,
                                                          user,
                                                          pw,
                                                          auto_pw_request,
                                                          close_stdin=True)
                if ok:
                    output = stdout.read()
                    error = stderr.read()
                    stdout.close()
                    stderr.close()
                    if error:
                        rospy.logwarn("ERROR while start '%s': %s", name,
                                      error)
                        raise StartException(''.join(
                            ['The host "', host, '" reports:\n', error]))

    #          from python_qt_binding import QtGui
    #          QtGui.QMessageBox.warning(None, 'Error while remote start %s'%str(name),
    #                                      str(''.join(['The host "', host, '" reports:\n', error])),
    #                                      QtGui.QMessageBox.Ok)
                    if output:
                        rospy.logdebug("STDOUT while start '%s': %s", name,
                                       output)
                else:
                    if error:
                        rospy.logwarn("ERROR while start '%s': %s", name,
                                      error)
                        raise StartException(''.join(
                            ['The host "', host, '" reports:\n', error]))
            except nm.AuthenticationRequest as e:
                raise nm.InteractionNeededError(
                    e, cls.runNodeWithoutConfig,
                    (host, package, binary, name, args, masteruri,
                     auto_pw_request))
Example #24
0
    def runNodeWithoutConfig(cls,
                             host,
                             package,
                             type,
                             name,
                             args=[],
                             masteruri=None,
                             auto_pw_request=True,
                             user=None,
                             pw=None):
        '''
    Start a node with using a launch configuration.
    @param host: the host or ip to run the node
    @type host: C{str} 
    @param package: the ROS package containing the binary
    @type package: C{str} 
    @param type: the binary of the node to execute
    @type type: C{str} 
    @param name: the ROS name of the node (with name space)
    @type name: C{str} 
    @param args: the list with arguments passed to the binary
    @type args: C{[str, ...]} 
    @raise Exception: on errors while resolving host
    @see: L{node_manager_fkie.is_local()}
    '''
        # create the name with namespace
        args2 = list(args)
        fullname = roslib.names.ns_join(roslib.names.SEP, name)
        for a in args:
            if a.startswith('__ns:='):
                fullname = roslib.names.ns_join(a.replace('__ns:=', ''), name)
        args2.append(''.join(['__name:=', name]))
        # run on local host
        if nm.is_local(host):
            try:
                cmd = roslib.packages.find_node(package, type)
            except roslib.packages.ROSPkgException as e:
                # multiple nodes, invalid package
                raise StartException(str(e))
            # handle different result types str or array of string
            import types
            if isinstance(cmd, types.StringTypes):
                cmd = [cmd]
            cmd_type = ''
            if cmd is None or len(cmd) == 0:
                raise StartException(' '.join(
                    [type, 'in package [', package, '] not found!']))
            if len(cmd) > 1:
                # Open selection for executables
                #        try:
                #          from PySide import QtGui
                #          item, result = QtGui.QInputDialog.getItem(None, ' '.join(['Multiple executables', type, 'in', package]),
                #                                            'Select an executable',
                #                                            cmd, 0, False)
                #          if result:
                #            #open the selected screen
                #            cmd_type = item
                #          else:
                #            return
                #        except:
                err = [
                    ''.join([
                        'Multiple executables with same name in package [',
                        package, ']  found:'
                    ])
                ]
                err.extend(cmd)
                raise StartException('\n'.join(err))
            else:
                cmd_type = cmd[0]
            cmd_str = str(' '.join(
                [nm.screen().getSceenCmd(fullname), cmd_type,
                 ' '.join(args2)]))
            rospy.loginfo("Run without config: %s", cmd_str)
            ps = None
            if not masteruri is None:
                cls._prepareROSMaster(masteruri)
                new_env = dict(os.environ)
                new_env['ROS_MASTER_URI'] = masteruri
                ps = subprocess.Popen(shlex.split(cmd_str), env=new_env)
            else:
                ps = subprocess.Popen(shlex.split(cmd_str))
            # wait for process to avoid 'defunct' processes
            thread = threading.Thread(target=ps.wait)
            thread.setDaemon(True)
            thread.start()
        else:
            # run on a remote machine
            startcmd = [
                nm.STARTER_SCRIPT, '--package',
                str(package), '--node_type',
                str(type), '--node_name',
                str(fullname)
            ]
            startcmd[len(startcmd):] = args2
            if not masteruri is None:
                startcmd.append('--masteruri')
                startcmd.append(masteruri)
            rospy.loginfo("Run remote on %s: %s", host, ' '.join(startcmd))
            try:
                output, error, ok = nm.ssh().ssh_exec(host, startcmd, user, pw,
                                                      auto_pw_request)
                if ok:
                    if error:
                        rospy.logwarn("ERROR while start '%s': %s", name,
                                      error)
                        raise StartException(''.join(
                            ['The host "', host, '" reports:\n', error]))

    #          from PySide import QtGui
    #          QtGui.QMessageBox.warning(None, 'Error while remote start %s'%str(name),
    #                                      str(''.join(['The host "', host, '" reports:\n', error])),
    #                                      QtGui.QMessageBox.Ok)
                    if output:
                        rospy.logdebug("STDOUT while start '%s': %s", name,
                                       output)
                else:
                    if error:
                        rospy.logwarn("ERROR while start '%s': %s", name,
                                      error)
                        raise StartException(''.join(
                            ['The host "', host, '" reports:\n', error]))
            except nm.AuthenticationRequest as e:
                raise nm.InteractionNeededError(
                    e, cls.runNodeWithoutConfig,
                    (host, package, type, name, args, masteruri,
                     auto_pw_request))
Example #25
0
    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
                    ])))
Example #26
0
 def runNodeWithoutConfig(cls, host, package, type, name, args=[]):
     '''
 Start a node with using a launch configuration.
 @param host: the host or ip to run the node
 @type host: C{str} 
 @param package: the ROS package containing the binary
 @type package: C{str} 
 @param type: the binary of the node to execute
 @type type: C{str} 
 @param name: the ROS name of the node (with name space)
 @type name: C{str} 
 @param args: the list with arguments passed to the binary
 @type args: C{[str, ...]} 
 @raise Exception: on errors while resolving host
 @see: L{node_manager_fkie.is_local()}
 '''
     # create the name with namespace
     fullname = ''.join(['/', name])
     for a in args:
         if a.startswith('__ns:='):
             fullname = ''.join(
                 ['/', a.replace('__ns:=', '').strip('/ '), fullname])
     fullname = fullname.replace('//', '/')
     args2 = list(args)
     args2.append(''.join(['__name:=', name]))
     # run on local host
     if nm.is_local(host):
         try:
             cmd = roslib.packages.find_node(package, type)
         except roslib.packages.ROSPkgException as e:
             # multiple nodes, invalid package
             raise StartException(str(e))
         # handle diferent result types str or array of string
         import types
         if isinstance(cmd, types.StringTypes):
             cmd = [cmd]
         cmd_type = ''
         if cmd is None or len(cmd) == 0:
             raise nm.StartException(' '.join(
                 [type, 'in package [', package, '] not found!']))
         if len(cmd) > 1:
             # Open selection for executables
             try:
                 from PySide import QtGui
                 item, result = QtGui.QInputDialog.getItem(
                     None,
                     ' '.join(['Multiple executables', type, 'in',
                               package]), 'Select an executable', cmd, 0,
                     False)
                 if result:
                     #open the selected screen
                     cmd_type = item
                 else:
                     return
             except:
                 raise nm.StartException(
                     'Multiple executables with same name in package found!'
                 )
         else:
             cmd_type = cmd[0]
         cmd_str = str(' '.join(
             [nm.screen().getSceenCmd(fullname), cmd_type,
              ' '.join(args2)]))
         rospy.loginfo("Run without config: %s", cmd_str)
         subprocess.Popen(shlex.split(cmd_str))
     else:
         # run on a remote machine
         startcmd = [
             nm.STARTER_SCRIPT, '--package',
             str(package), '--node_type',
             str(type), '--node_name',
             str(fullname)
         ]
         startcmd[len(startcmd):] = args2
         rospy.loginfo("Run remote: %s", ' '.join(startcmd))
         (stdin, stdout, stderr), ok = nm.ssh().ssh_exec(host, startcmd)
         if ok:
             stdin.close()
             error = stderr.read()
             if error:
                 rospy.logwarn("ERROR while start '%s': %s", name, error)
                 from PySide import QtGui
                 QtGui.QMessageBox.warning(
                     None, 'Error while remote start %s' % str(name),
                     str(''.join(
                         ['The host "', host, '" reports:\n', error])),
                     QtGui.QMessageBox.Ok)
             output = stdout.read()
             if output:
                 rospy.logdebug("STDOUT while start '%s': %s", name, output)
    def runNode(cls, runcfg):
        '''
        Start the node with given name from the given configuration.
        @param runcfg: the configuration containing the start parameter
        @type runcfg: AdvRunCfg
        @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 = runcfg.roslaunch_config.getNode(runcfg.node)
        if n is None:
            raise StartException(''.join(["Node '", runcfg.node, "' not found!"]))

        env = list(n.env_args)
        # set logging options
        if runcfg.logging is not None:
            if not runcfg.logging.is_default('console_format'):
                env.append(('ROSCONSOLE_FORMAT', '%s' % runcfg.logging.console_format))
        if n.respawn:
            # set the respawn environment variables
            respawn_params = cls._get_respawn_params(rospy.names.ns_join(n.namespace, n.name), runcfg.roslaunch_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 n.launch_prefix is not None else ''
        if prefix.lower() == 'screen' or prefix.lower().find('screen ') != -1:
            rospy.loginfo("SCREEN prefix removed before start!")
            prefix = ''
        args = ['__ns:=%s' % n.namespace.rstrip(rospy.names.SEP), '__name:=%s' % n.name]
        if n.cwd is not None:
            args.append('__cwd:=%s' % n.cwd)

        # add remaps
        for remap in n.remap_args:
            args.append(''.join([remap[0], ':=', remap[1]]))

        # get host of the node
        host = runcfg.roslaunch_config.hostname
        env_loader = ''
        if n.machine_name:
            machine = runcfg.roslaunch_config.Roscfg.machines[n.machine_name]
            if machine.address not in ['localhost', '127.0.0.1']:
                host = machine.address
                if runcfg.masteruri is None:
                    runcfg.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 runcfg.force2host is not None:
            host = runcfg.force2host

        # set the ROS_MASTER_URI
        if runcfg.masteruri is None:
            runcfg.masteruri = masteruri_from_ros()
            env.append(('ROS_MASTER_URI', runcfg.masteruri))
            ros_hostname = NameResolution.get_ros_hostname(runcfg.masteruri)
            if ros_hostname:
                env.append(('ROS_HOSTNAME', ros_hostname))

        abs_paths = list()  # tuples of (parameter name, old value, new value)
        not_found_packages = list()  # package names
        # set the global parameter
        if runcfg.masteruri is not None and runcfg.masteruri not in runcfg.roslaunch_config.global_param_done:
            global_node_names = cls.getGlobalParams(runcfg.roslaunch_config.Roscfg)
            rospy.loginfo("Register global parameter:\n  %s", '\n  '.join("%s%s" % (utf8(v)[:80], '...' if len(utf8(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(runcfg.masteruri, global_node_names, [], runcfg.user, runcfg.pw, runcfg.auto_pw_request)
            runcfg.roslaunch_config.global_param_done.append(runcfg.masteruri)

        # add params
        if runcfg.masteruri is not None:
            nodens = ''.join([n.namespace, n.name, rospy.names.SEP])
            params = dict()
            for param, value in runcfg.roslaunch_config.Roscfg.params.items():
                if param.startswith(nodens):
                    params[param] = value
            clear_params = []
            for cparam in runcfg.roslaunch_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" % (utf8(v)[:80], '...' if len(utf8(v)) > 80 else'') for v in params.values()))
            abs_paths[len(abs_paths):], not_found_packages[len(not_found_packages):] = cls._load_parameters(runcfg.masteruri, params, clear_params, runcfg.user, runcfg.pw, runcfg.auto_pw_request)
        # 'print "RUN prepared", node, time.time()

        if nm.is_local(host, wait=True):
            nm.screen().testScreen()
            if runcfg.executable:
                cmd_type = runcfg.executable
            else:
                try:
                    cmd = roslib.packages.find_node(n.package, n.type)
                except (Exception, roslib.packages.ROSPkgException) as starterr:
                    # multiple nodes, invalid package
                    raise StartException("Can't find resource: %s" % starterr)
                # 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("%s in package [%s] not found!\n\nThe package "
                                         "was created?\nIs the binary executable?\n" % (n.type, n.package))
                if len(cmd) > 1:
                    if runcfg.auto_pw_request:
                        # Open selection for executables, only if the method is called from the main GUI thread
                        try:
                            try:
                                from python_qt_binding.QtGui import QInputDialog
                            except:
                                from python_qt_binding.QtWidgets import QInputDialog
                            item, result = QInputDialog.getItem(None, 'Multiple executables %s in %s' % (n.type, 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,
                                                        (runcfg,))
                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(runcfg.masteruri)
            node_cmd = [nm.settings().respawn_script if n.respawn else '', prefix, cmd_type]
            cmd_args = [nm.screen().getSceenCmd(runcfg.node)]
            cmd_args[len(cmd_args):] = node_cmd
            cmd_args.append(utf8(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'] = runcfg.masteruri
            ros_hostname = NameResolution.get_ros_hostname(runcfg.masteruri)
            if ros_hostname:
                new_env['ROS_HOSTNAME'] = ros_hostname
            # add the namespace environment parameter to handle some cases,
            # e.g. rqt_cpp plugins
            if n.namespace:
                new_env['ROS_NAMESPACE'] = n.namespace
            # set logging options
            if runcfg.logging is not None:
                if not runcfg.logging.is_default('loglevel'):
                    env.append(('ROSCONSOLE_CONFIG_FILE', nm.settings().rosconsole_cfg_file(n.package)))
            for key, value in env:
                new_env[key] = value
            SupervisedPopen(shlex.split(utf8(' '.join(cmd_args))), cwd=cwd,
                            env=new_env, object_id="Run node", description="Run node "
                            "[%s]%s" % (utf8(n.package), utf8(n.type)))
            nm.filewatcher().add_binary(cmd_type, runcfg.node, runcfg.masteruri, runcfg.roslaunch_config.Filename)
        else:
            # 'print "RUN REMOTE", node, time.time()
            # start remote
            if runcfg.roslaunch_config.PackageName is None:
                raise StartException("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, runcfg.user, runcfg.pw, runcfg.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, (runcfg,))

            startcmd = [env_command, nm.settings().start_remote_script,
                        '--package', utf8(n.package),
                        '--node_type', utf8(n.type),
                        '--node_name', utf8(runcfg.node),
                        '--node_respawn true' if n.respawn else '']
            if runcfg.masteruri is not None:
                startcmd.append('--masteruri')
                startcmd.append(runcfg.masteruri)
            if prefix:
                startcmd[len(startcmd):] = ['--prefix', prefix]
            if runcfg.logging is not None:
                if not runcfg.logging.is_default('loglevel'):
                    startcmd.append('--loglevel')
                    startcmd.append(nm.settings().logging.loglevel)

            # 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, runcfg.user, runcfg.pw, runcfg.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, utf8(' '.join(startcmd)))
                # 'print "RUN CALL", node, time.time()
                _, stdout, stderr, ok = nm.ssh().ssh_exec(host, startcmd, runcfg.user, runcfg.pw, runcfg.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, (runcfg,))

            if ok:
                if error:
                    rospy.logwarn("ERROR while start '%s': %s", runcfg.node, error)
                    raise StartException(utf8(''.join(['The host "', host, '" reports:\n', error])))
                if output:
                    rospy.loginfo("STDOUT while start '%s': %s", runcfg.node, output)
            # inform about absolute paths in parameter value
            if len(abs_paths) > 0:
                rospy.loginfo("Absolute paths found while start:\n%s", utf8('\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(utf8('\n'.join(['Some absolute paths are not renamed because following packages are not found on remote host:', packages])))
Example #28
0
    def runNode(cls, node, launch_config):
        '''
    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} 
    @raise StartException: if the screen is not available on host.
    @raise Exception: on errors while resolving host
    @see: L{node_manager_fkie.is_local()}
    '''
        n = launch_config.getNode(node)
        if n is None:
            raise StartException(''.join(["Node '", node, "' not found!"]))

        env = list(n.env_args)
        prefix = n.launch_prefix if not n.launch_prefix is None else ''
        # thus the parameters while the transfer are not separated
        if prefix:
            prefix = ''.join(['"', prefix, '"'])
        args = [
            ''.join(['__ns:=', n.namespace]), ''.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]
            host = machine.address
            #TODO: env-loader support?


#      if hasattr(machine, "env_loader") and machine.env_loader:
#        env_loader = machine.env_loader

        masteruri = nm.nameres().getUri(host=host)
        # set the ROS_MASTER_URI
        if masteruri is None:
            env.append(('ROS_MASTER_URI', nm.masteruri_from_ros()))

        # 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(global_node_names))
            cls._load_parameters(masteruri, global_node_names, [])
            launch_config.global_param_done.append(masteruri)

        # add params
        if not masteruri is None:
            nodens = ''.join([n.namespace, n.name, '/'])
            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(param)
            rospy.loginfo("Register parameter:\n%s", '\n'.join(params))
            cls._load_parameters(masteruri, params, clear_params)
        if nm.is_local(host):
            nm.screen().testScreen()
            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
            import types
            if isinstance(cmd, types.StringTypes):
                cmd = [cmd]
            cmd_type = ''
            if cmd is None or len(cmd) == 0:
                raise nm.StartException(' '.join([
                    n.type, 'in package [', n.package,
                    '] not found!\n\nThe package was created?\nIs the binary executable?\n'
                ]))
            if len(cmd) > 1:
                # Open selection for executables
                try:
                    from PySide 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 nm.StartException(
                        'Multiple executables with same name in package found!'
                    )
            else:
                cmd_type = cmd[0]
            node_cmd = [prefix, cmd_type]
            cmd_args = [nm.screen().getSceenCmd(node)]
            cmd_args[len(cmd_args):] = node_cmd
            cmd_args.append(n.args)
            cmd_args[len(cmd_args):] = args
            rospy.loginfo("RUN: %s", ' '.join(cmd_args))
            subprocess.Popen(shlex.split(str(' '.join(cmd_args))))
        else:
            # start remote
            if launch_config.PackageName is None:
                raise StartException(''.join(
                    ["Can't run remote without a valid package name!"]))
            # setup environment
            env_command = ''
            if env_loader:
                rospy.logwarn(
                    "env_loader in machine tag currently not supported")
                raise nm.StartException(
                    "env_loader in machine tag currently not supported")
            if env:
                env_command = "env " + ' '.join(
                    ["%s=%s" % (k, v) for (k, v) in env])

            startcmd = [
                env_command, nm.STARTER_SCRIPT, '--package',
                str(n.package), '--node_type',
                str(n.type), '--node_name',
                str(node)
            ]
            if prefix:
                startcmd[len(startcmd):] = ['--prefix', prefix]

            startcmd[len(startcmd):] = n.args
            startcmd[len(startcmd):] = args
            rospy.loginfo("Run remote: %s", ' '.join(startcmd))
            (stdin, stdout, stderr), ok = nm.ssh().ssh_exec(host, startcmd)

            if ok:
                stdin.close()
                #      stderr.close()
                #      stdout.close()
                error = stderr.read()
                if error:
                    rospy.logwarn("ERROR while start '%s': %s", node, error)
                    raise nm.StartException(
                        str(''.join(
                            ['The host "', host, '" reports:\n', error])))
                output = stdout.read()
                if output:
                    rospy.logdebug("STDOUT while start '%s': %s", node, output)