def __init__(self):
     """
     Creates a new list model.
     """
     QStandardItemModel.__init__(self)
     self.setColumnCount(len(ParameterModel.header))
     self.setHorizontalHeaderLabels([label for label, _ in ParameterModel.header])
Esempio n. 2
0
 def __init__(self):
     """
     Initializes the ModelLogger.
     """
     self.__log_model = QStandardItemModel(0, 4, None)
     self.__log_model.setHorizontalHeaderLabels(
         ["type", "date", "location", "message"])
Esempio n. 3
0
 def __init__(self, parent=None, progress_queue=None, viewobj=None):
     '''
     Creates a new list model.
     '''
     QStandardItemModel.__init__(self, parent)
     self.viewobj = viewobj
     self.setColumnCount(len(LaunchListModel.header))
     self.setHorizontalHeaderLabels(
         [label for label, _width in LaunchListModel.header])
     self.pyqt_workaround = dict(
     )  # workaround for using with PyQt: store the python object to keep the defined attributes in the TopicItem subclass
     self.items = []
     self._roots = {}
     self._current_path = nmdurl.nmduri()
     self._current_master = masteruri_from_master()
     self._current_master_name = ''
     self.ros_root_paths = {}  # {url: [root pasth(str)]}
     self.ros_root_paths[self._current_path] = [
         os.path.normpath(p)
         for p in os.getenv("ROS_PACKAGE_PATH").split(':')
     ]
     self._progress_queue = progress_queue
     nm.nmd().file.listed_path.connect(self._listed_path)
     nm.nmd().file.packages_available.connect(self._on_new_packages)
     nm.nmd().file.error.connect(self._nmd_error)
Esempio n. 4
0
    def _init_monitor_parameters(self,
                                 params_monitored,
                                 _col_names_paramtable=None):
        """
        @type params_monitored: str[]
        """
        self._params_monitored = params_monitored

        self._param_datamodel = QStandardItemModel(0, 2)
        self._root_qitem = self._param_datamodel.invisibleRootItem()
        self._view_params.setModel(self._param_datamodel)

        # Names of header on the QTableView.
        if not _col_names_paramtable:
            _col_names_paramtable = [
                'Param name', 'Found on Parameter Server?'
            ]
        self._param_datamodel.setHorizontalHeaderLabels(_col_names_paramtable)

        self.sig_param.connect(self._update_output_parameters)

        param_check_thread = Thread(target=self._check_params_alive,
                                    args=(self.sig_param,
                                          self._params_monitored))
        return param_check_thread
Esempio n. 5
0
    def __init__(self):
        super(NodeSelectorWidget, self).__init__()
        self.stretch = None

        ui_file = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                               'ui/node_selector.ui')
        loadUi(ui_file, self)

        #  Setup treeview and models
        self._std_model = QStandardItemModel()
        self._node_selector_view.setModel(self._std_model)
        self._rootitem = self._std_model.invisibleRootItem()

        self._nodes_previous = None

        # Calling this method updates the list of the node.
        # Initially done only once.
        self._update_nodetree()

        # Setting slot for when user clickes on QTreeView.
        selectionModel = self._node_selector_view.selectionModel()
        selectionModel.selectionChanged.connect(self._selection_changed_slot)

        #TODO(Isaac): Needs auto-update function enabled, once another function
        #             that updates node tree with maintaining collapse/expansion
        #             state. http://goo.gl/GuwYp can be a help.

        #        self.timer = QTimer()
        #        self.timer.timeout.connect(self._refresh_nodes)
        #        self.timer.start(5000) #  5sec interval is fast enough.

        self._collapse_button.pressed.connect(
            self._node_selector_view.collapseAll)
        self._expand_button.pressed.connect(self._node_selector_view.expandAll)
Esempio n. 6
0
 def __init__(self):
     '''
     Creates a new list model.
     '''
     QStandardItemModel.__init__(self)
     self.setColumnCount(len(ParameterModel.header))
     self.setHorizontalHeaderLabels([label for label, _ in ParameterModel.header])
Esempio n. 7
0
    def __init__(self,
                 rocon_master_uri='localhost',
                 host_name='localhost',
                 with_rqt=False):
        self.with_rqt = with_rqt
        self.widget = QWidget()
        self.pairings_view_model = QStandardItemModel()
        self.interactions_view_model = QStandardItemModel()
        self.interactions_remocon = InteractionsRemocon(
            rocon_master_uri, host_name)
        self.interactions_remocon.connect(
            [self.update_group_combobox, self.refresh_grids])
        self.interactions_remocon.connect(
            [self.update_pairings_group_combobox, self.refresh_grids])
        self.default_group = "All"

        rospack = rospkg.RosPack()
        ui_file = os.path.join(rospack.get_path('rocon_remocon'), 'ui',
                               'interactions_chooser.ui')
        loadUi(ui_file, self.widget, {})

        # create a few directories for caching icons and ...
        utils.setup_home_dirs()
        self._init_ui()
        self._init_events()
 def __init__(self):
     '''
     Creates a new list model.
     '''
     QStandardItemModel.__init__(self)
     self.setColumnCount(len(ServiceModel.header))
     self.setHorizontalHeaderLabels([label for label, _ in ServiceModel.header])
     self.pyqt_workaround = dict()  # workaround for using with PyQt: store the python object to keep the defined attributes in the ServiceItem subclass
 def __init__(self):
     '''
     Creates a new list model.
     '''
     QStandardItemModel.__init__(self)
     self.setColumnCount(len(SettingsModel.header))
     self.setHorizontalHeaderLabels([label for label, _ in SettingsModel.header])
     self.pyqt_workaround = dict()  # workaround for using with PyQt: store the python object to keep the defined attributes in the TopicItem subclass
Esempio n. 10
0
 def __init__(self, local_masteruri=None):
     '''
     Creates a new list model.
     '''
     QStandardItemModel.__init__(self)
     self.setColumnCount(len(MasterModel.header))
     self._masteruri = local_masteruri
     self.parent_view = None
     self.pyqt_workaround = dict()  # workaround for using with PyQt: store the python object to keep the defined attributes in the MasterItem subclass
 def setData(self, index, value, role):
     if (index.column() == 3 and 
         index.model().data(index.model().index(index.row(), index.column() - 2, index.parent()), Qt.DisplayRole) == "bool"): 
         if (role == Qt.CheckStateRole):
             stringVal = "False"
             if (value == Qt.Checked):
                 stringVal = "True"
             return QStandardItemModel.setData(self, index, stringVal, Qt.EditRole)
     return QStandardItemModel.setData(self, index, value, role)
Esempio n. 12
0
 def __init__(self, local_masteruri=None):
     '''
     Creates a new list model.
     '''
     QStandardItemModel.__init__(self)
     self.setColumnCount(len(MasterModel.header))
     self._masteruri = local_masteruri
     self.parent_view = None
     self.pyqt_workaround = dict()  # workaround for using with PyQt: store the python object to keep the defined attributes in the MasterItem subclass
Esempio n. 13
0
 def setData(self, index, value, role):
     if (index.column() == index.column() ==
             self._column_index['expression'] and index.model().data(
                 index.model().index(
                     index.row(), self._column_index['type'],
                     index.parent()), Qt.DisplayRole) == 'bool'):
         if role == Qt.CheckStateRole:
             value = str(value == Qt.Checked)
             return QStandardItemModel.setData(self, index, value,
                                               Qt.EditRole)
     return QStandardItemModel.setData(self, index, value, role)
Esempio n. 14
0
    def __init__(self, context):
        super(ChatbotGUI, self).__init__(context)
        self.setObjectName('ChatbotGUI')
        from argparse import ArgumentParser
        parser = ArgumentParser()
        parser.add_argument("-q",
                            "--quiet",
                            action="store_true",
                            dest="quiet",
                            help="Put plugin in silent mode")
        args, unknowns = parser.parse_known_args(context.argv())
        if not args.quiet:
            print 'arguments: ', args
            print 'unknowns: ', unknowns

        self._widget = QWidget()
        ui_file = os.path.join(rospkg.RosPack().get_path('chatbot_gui'),
                               'resource', 'ChatbotGUI.ui')
        loadUi(ui_file, self._widget, {'NavViewWidget': NavViewWidget})
        self._widget.setObjectName('ChatbotGUIUi')
        if context.serial_number() > 1:
            self._widget.setWindowTitle(self._widget.windowTitle() +
                                        (' (%d)' % context.serial_number()))
        context.add_widget(self._widget)

        self._widget.pickDone.clicked[bool].connect(self._handle_pick_clicked)
        self._widget.placeDone.clicked[bool].connect(
            self._handle_place_clicked)
        self._widget.textSay.keyPressEvent = self._handle_custom_keypress
        #ros stuff
        self.pubPick = rospy.Publisher('picker', String, queue_size=10)
        self.pubPlace = rospy.Publisher('placer', String, queue_size=10)
        self.pubRecog = rospy.Publisher('recognition/raw_result',
                                        String,
                                        queue_size=10)
        self.subRecog = rospy.Subscriber("recognition/raw_result", String,
                                         self._recog_callback)
        self.subLog = rospy.Subscriber("chatbot_gui/log", String,
                                       self._log_callback)
        self.subStatus = rospy.Subscriber("chatbot_gui/status", String,
                                          self._status_callback)

        self.model = QStandardItemModel()
        self.model.setColumnCount(2)
        headerNames = []
        headerNames.append("Timestamp")
        headerNames.append("Message")
        self.model.setHorizontalHeaderLabels(headerNames)
        self._widget.tableLog.setModel(self.model)
        self._widget.tableLog.horizontalHeader().setStretchLastSection(True)
        self._widget.tableLog.setColumnWidth(0, 170)
        self._message_limit = 20000
        self._message_count = 0
Esempio n. 15
0
    def __init__(self, parent):
        """
        @type parent: LaunchMain
        """
        super(LaunchWidget, self).__init__()
        self._parent = parent

        self._config = None
        self._settings = QSettings('ros', 'rqt_launch')
        self._settings.sync()
        self._package_update = False
        self._launchfile_update = False

        # TODO: should be configurable from gui
        self._port_roscore = 11311

        self._run_id = None

        self._rospack = rospkg.RosPack()
        ui_file = os.path.join(
            self._rospack.get_path('rqt_launch'), 'resource', 'launch_widget.ui'
        )
        loadUi(ui_file, self)

        # row=0 allows any number of rows to be added.
        self._datamodel = QStandardItemModel(0, 1)

        master_uri = rosenv.get_master_uri()
        rospy.loginfo('LaunchWidget master_uri={}'.format(master_uri))
        self._delegate = NodeDelegate(master_uri, self._rospack)
        self._treeview.setModel(self._datamodel)
        self._treeview.setItemDelegate(self._delegate)

        # NodeController used in controller class for launch operation.
        self._node_controllers = []

        self._pushbutton_load_params.clicked.connect(self._parent.load_params)
        self._pushbutton_start_all.clicked.connect(self._parent.start_all)
        self._pushbutton_stop_all.clicked.connect(self._parent.stop_all)
        self._pushbutton_refresh.clicked.connect(
            self._update_pkgs_contain_launchfiles
        )
        # Bind package selection with .launch file selection.
        self._combobox_pkg.currentIndexChanged[str].connect(
            self._refresh_launchfiles
        )
        # Bind a launch file selection with launch GUI generation.
        self._combobox_launchfile_name.currentIndexChanged[str].connect(
            self._load_launchfile_slot
        )
        self._update_pkgs_contain_launchfiles()
Esempio n. 16
0
 def __init__(self):
     '''
     Creates a new list model.
     '''
     QStandardItemModel.__init__(self)
     self.setColumnCount(len(TopicModel.header))
     self.setHorizontalHeaderLabels([label for label, _ in TopicModel.header])
     topics = ['/rosout', '/rosout_agg', '/diagnostics_agg']
     def_list = ['\A' + n.strip().replace('*', '.*') + '\Z' for n in topics]
     self._re_cap_systopics = re.compile('|'.join(def_list), re.I)
     self.pyqt_workaround = dict()  # workaround for using with PyQt: store the python object to keep the defined attributes in the TopicItem subclass
     root_items = TopicGroupItem.create_item_list(rospy.names.SEP, self.invisibleRootItem(), False)
     self.invisibleRootItem().appendRow(root_items)
     self._pyqt_workaround_add(rospy.names.SEP, root_items[0])
Esempio n. 17
0
    def _init_variables(self):
        self.initialised = False

        #init
        self._qt_rapp_manager_info = QtRappManagerInfo(self._refresh_rapps)
        self._update_rapps_signal.connect(self._update_rapp_list)

        self._rapp_view_model = QStandardItemModel()
        self._widget.rapp_grid.setModel(self._rapp_view_model)
        self._widget.rapp_grid.setWrapping(True)
        self._widget.rapp_grid.setIconSize(QSize(60, 60))
        self._widget.rapp_grid.setSpacing(10)

        self._selected_rapp = None
Esempio n. 18
0
 def __init__(self):
     '''
     Creates a new list model.
     '''
     QStandardItemModel.__init__(self)
     self.setColumnCount(len(LaunchListModel.header))
     self.setHorizontalHeaderLabels([label for label, _width in LaunchListModel.header])
     self.pyqt_workaround = dict()  # workaround for using with PyQt: store the python object to keep the defined attributes in the TopicItem subclass
     self.items = []
     self.DIR_CACHE = {}
     self.currentPath = None
     self.root_paths = [os.path.normpath(p) for p in os.getenv("ROS_PACKAGE_PATH").split(':')]
     self._setNewList(self._moveUp(None))
     self.__packages = {}
     self._fill_packages_thread = PackagesThread()
Esempio n. 19
0
    def _init_monitor_nodes(self):
        """
        @rtype: Thread
        """
        self._node_datamodel = QStandardItemModel(0, 2)
        self._root_qitem = self._node_datamodel.invisibleRootItem()
        self._view_nodes.setModel(self._node_datamodel)

        node_monitor_thread = threading.Thread(target=self._check_nodes_alive,
                                               args=(self.sig_node,
                                                     self._nodes_monitored,
                                                     self._stop_event))

        self.sig_node.connect(self._update_output_nodes)
        return node_monitor_thread
 def __init__(self):
     '''
     Creates a new list model.
     '''
     QStandardItemModel.__init__(self)
     self.setColumnCount(len(LaunchListModel.header))
     self.setHorizontalHeaderLabels([label for label, _width in LaunchListModel.header])
     self.pyqt_workaround = dict()  # workaround for using with PyQt: store the python object to keep the defined attributes in the TopicItem subclass
     self.items = []
     self.DIR_CACHE = {}
     self.currentPath = None
     self.root_paths = [os.path.normpath(p) for p in os.getenv("ROS_PACKAGE_PATH").split(':')]
     self._setNewList(self._moveUp(None))
     self.__packages = {}
     self._fill_packages_thread = PackagesThread()
Esempio n. 21
0
    def __init__(self, mode, dotgraph , dotcode_factory, dotparser , param_manager, models_desc_file_path, nodename='', parent = None):
        super(InferenceDialog, self).__init__(parent)



        if mode not in ['add','edit']:
            raise Exception('wrong mode for InferenceDialog')
        
    
        self.nodename = nodename

        self.setWindowTitle("Dialog")
        self.setGeometry(300,300,450,250)

        # self._widget = QDialog()

        ui_file = os.path.join(rospkg.RosPack().get_path('rqt_vino_plugin'), 'resource', 'add_inference_dialog.ui')
        loadUi(ui_file, self)
        

        self.dotgraph = dotgraph
        self.dotparser = dotparser
        self.dotcode_factory = dotcode_factory
 
 
        self.available_infers_list = param_manager.parse_inferlist_file(models_desc_file_path)
        


        # self.node_name_lineedit.textEdited.connect(self._edit_infer_name)
        #self.node_infer_name_combobox.activated.connect(self.update_infer_names)
        self.node_infer_combobox.currentTextChanged.connect(self._select_infer_type)

        self.connect_from_listmodel = QStandardItemModel()#(self.connect_from_listview)
        self.connect_to_listmodel = QStandardItemModel()#(self.connect_to_listview)

        # self.connect_from_listmodel.itemChanged.connect(self._connect_from_changed)
        
        #self.connect_to_listview.setModel(self.connect_to_listmodel)

      
        self.update_infer_names()
        self.update_connect_from_list()

        if mode == 'add':
            self.buttonBox.accepted.connect(self._create_node_in_graph)
        elif mode == 'edit':
            self.buttonBox.accepted.connect(self._edit_node_in_graph)
Esempio n. 22
0
 def __init__(self, tabwidget, parent=None):
     QDockWidget.__init__(self, "LaunchGraph", parent)
     graph_ui_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'GraphDockWidget.ui')
     loadUi(graph_ui_file, self)
     self.setObjectName('LaunchGraph')
     self.setFeatures(QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetFloatable)
     self._info_icon = QIcon(":/icons/info.png")
     self._tabwidget = tabwidget
     self._current_path = None
     self._root_path = None
     self._current_deep = 0
     self.graphTreeView.setSelectionBehavior(QAbstractItemView.SelectRows)
     model = QStandardItemModel()
     self.graphTreeView.setModel(model)
     self.graphTreeView.setUniformRowHeights(True)
     self.graphTreeView.header().hide()
     self.htmlDelegate = HTMLDelegate(palette=self.palette())
     self.graphTreeView.setItemDelegateForColumn(0, self.htmlDelegate)
     self.graphTreeView.activated.connect(self.on_activated)
     self.graphTreeView.clicked.connect(self.on_clicked)
     self._created_tree = False
     self.has_none_packages = True
     self.has_warnings = False
     self._refill_tree([], False)
     self._fill_graph_thread = None
Esempio n. 23
0
    def __init__(self):
        super(TreeviewWidgetSelectProve, self).__init__()

        rp = rospkg.RosPack()
        ui_file = os.path.join(rp.get_path('rqt_prove'), 'resource',
                               #'treeview_non_custom.ui')  # Works with pyqt.
                               'treeview_with_custom.ui')  # No good.
        #loadUi(ui_file, self)
        loadUi(ui_file, self, {'CustomQTreeview': CustomQTreeview})

        self._std_model = QStandardItemModel()
        self._rootitem = self._std_model.invisibleRootItem()

        item_r_1 = QStandardItem("r1")

        self._rootitem.appendRow(item_r_1)

        print('_rootitem index={}'.format(self._rootitem.index()))

        self.treeview.setModel(self._std_model)
        self.selectionModel = self.treeview.selectionModel()
        self.selectionModel.selectionChanged.connect(
                                                 self._selection_changed_slot)

        print('del/sel?\tde/sel index\tde/sel.row\tde/sel.dat\tparent\tinternal id')

        self.show()
 def flags(self, index):
     # FIXME hardcoded column number
     flags = QStandardItemModel.flags(self, index) 
     if (index.column() == 3 and 
         index.model().data(index.model().index(index.row(), index.column() - 2, index.parent()), Qt.DisplayRole) == "bool"):
         flags = flags | Qt.ItemIsUserCheckable | Qt.ItemIsEditable | Qt.ItemIsEnabled
     return flags
Esempio n. 25
0
    def _init_monitor_nodes(self, nodes_monitored):
        """
        @type params_monitored: str[]
        @rtype: Thread
        """
        self._node_datamodel = QStandardItemModel(0, 2)
        self._root_qitem = self._node_datamodel.invisibleRootItem()
        self._view_nodes.setModel(self._node_datamodel)

        node_monitor_thread = Thread(target=self._check_nodes_alive,
                                     args=(self.sig_node,
                                           self._nodes_monitored))
        #        self._node_monitor_thread = NodeMonitorThread(self, self.sig_node,
        #                                                      nodes_monitored)
        self.sig_node.connect(self._update_output_nodes)
        return node_monitor_thread
class TestRqtRosGraph(unittest.TestCase):
    """
    :author: Isaac Saito
    """

    def setUp(self):
        unittest.TestCase.setUp(self)

        self._model = QStandardItemModel()
        node1 = QStandardItem('node1')
        self._node1_1 = QStandardItem('node1_1')
        self._node1_1_1 = QStandardItem('node1_1_1')
        node1_1_2 = QStandardItem('node1_1_2')
        node1_2 = QStandardItem('node1_2')

        node1.appendRow(self._node1_1)
        self._node1_1.appendRow(self._node1_1_1)
        self._node1_1.appendRow(node1_1_2)
        node1.appendRow(node1_2)

        self._model.appendRow(node1)

        #node_list = [node1, node1_1, self._node1_1_1, node1_1_2, node1_2]
        #self._model.appendRow(node_list)

        self._grn_node1_1_1 = '/node1/node1_1/node1_1_1'
        self._len_lower_grn_node1_1 = 2

    def tearDown(self):
        unittest.TestCase.tearDown(self)
        del self._model

    def test_get_upper_grn(self):
        self.assertEqual(RqtRosGraph.get_upper_grn(self._node1_1_1.index(), ''),
                         self._grn_node1_1_1)

    def test_get_lower_grn_dfs(self):
        self.assertEqual(len(RqtRosGraph.get_lower_grn_dfs(
                                                  self._node1_1.index(),
                                                  '')),
                         self._len_lower_grn_node1_1)

    def test_get_full_grn(self):
        self.assertEqual(RqtRosGraph.get_full_grn(self._node1_1_1.index()),
                         self._grn_node1_1_1)
class TestRqtRosGraph(unittest.TestCase):
    """
    :author: Isaac Saito
    """
    def setUp(self):
        unittest.TestCase.setUp(self)

        self._model = QStandardItemModel()
        node1 = QStandardItem('node1')
        self._node1_1 = QStandardItem('node1_1')
        self._node1_1_1 = QStandardItem('node1_1_1')
        node1_1_2 = QStandardItem('node1_1_2')
        node1_2 = QStandardItem('node1_2')

        node1.appendRow(self._node1_1)
        self._node1_1.appendRow(self._node1_1_1)
        self._node1_1.appendRow(node1_1_2)
        node1.appendRow(node1_2)

        self._model.appendRow(node1)

        # node_list = [node1, node1_1, self._node1_1_1, node1_1_2, node1_2]
        # self._model.appendRow(node_list)

        self._grn_node1_1_1 = '/node1/node1_1/node1_1_1'
        self._len_lower_grn_node1_1 = 2

    def tearDown(self):
        unittest.TestCase.tearDown(self)
        del self._model

    def test_get_upper_grn(self):
        self.assertEqual(
            RqtRosGraph.get_upper_grn(self._node1_1_1.index(), ''),
            self._grn_node1_1_1)

    def test_get_lower_grn_dfs(self):
        self.assertEqual(
            len(RqtRosGraph.get_lower_grn_dfs(self._node1_1.index(), '')),
            self._len_lower_grn_node1_1)

    def test_get_full_grn(self):
        self.assertEqual(RqtRosGraph.get_full_grn(self._node1_1_1.index()),
                         self._grn_node1_1_1)
Esempio n. 28
0
    def _render_messages(self, *messages):
        """Render simple messages on the canvas"""

        msg_dot = pydot.Dot()

        for msg in messages:
            msg_dot.add_node(pydot.Node(str(uuid.uuid4()), label=str(msg)))

        self._render_dotgraph(msg_dot)
        self._render_debug_data(QStandardItemModel(self._scene))
 def data(self, index, role):
     # FIXME hardcoded column number
     if (index.column() == 3 and 
         index.model().data(index.model().index(index.row(), index.column() - 2, index.parent()), Qt.DisplayRole) == "bool"): 
         if (role == Qt.CheckStateRole):
             value = index.model().data(index.model().index(index.row(), index.column(), index.parent()), Qt.DisplayRole)
             if (value == "True"):
                 return Qt.Checked
             else:
                 return Qt.Unchecked
     return QStandardItemModel.data(self, index, role)
Esempio n. 30
0
    def _init_monitor_nodes(self, nodes_monitored):
        """
        @type params_monitored: str[]
        """
        self._node_datamodel = QStandardItemModel(0, 2)
        self._root_qitem = self._node_datamodel.invisibleRootItem()
        self._view_nodes.setModel(self._node_datamodel)

        self._node_monitor_thread = NodeMonitorThread(self, self.sig_node,
                                                      nodes_monitored)
        self.sig_node.connect(self._monitor_nodes)
        self._node_monitor_thread.start()
Esempio n. 31
0
    def _init_monitor_parameters(self, params_monitored):
        """
        @type params_monitored: str[]
        """
        self._param_datamodel = QStandardItemModel(0, 2)
        self._root_qitem = self._param_datamodel.invisibleRootItem()
        self._view_reconf.setModel(self._param_datamodel)

        self._param_check_thread = ParamCheckThread(self, self.sig_param,
                                                    params_monitored)
        self.sig_param.connect(self._monitor_parameters)
        self._param_check_thread.start()
Esempio n. 32
0
    def __init__(self,
                 mode,
                 dotgraph,
                 dotcode_factory,
                 dotparser,
                 param_manager,
                 models_desc_file_path,
                 nodename='',
                 parent=None):
        super(OutputDialog, self).__init__(parent)

        if mode not in ['add', 'edit']:
            raise Exception('Wrong mode for Ouput Dialog')

        self.setWindowTitle("Add a output pipe")
        self.setGeometry(300, 300, 450, 250)

        # self._widget = QDialog()

        ui_file = os.path.join(rospkg.RosPack().get_path('rqt_vino_plugin'),
                               'resource', 'add_output_dialog.ui')
        loadUi(ui_file, self)

        self.dotgraph = dotgraph
        self.dotparser = dotparser
        self.dotcode_factory = dotcode_factory

        self.available_infers_list = param_manager.parse_inferlist_file(
            models_desc_file_path)

        self.connect_from_listmodel = QStandardItemModel()
        self.output_type_combobox.currentTextChanged.connect(
            self._update_display)
        self.update_output_types()

        if mode == 'add':
            self.buttonBox.accepted.connect(self._create_node_in_graph)
        elif mode == 'edit':
            self.nodename = nodename
            self.buttonBox.accepted.connect(self._edit_node_in_graph)
    def setUp(self):
        unittest.TestCase.setUp(self)

        self._model = QStandardItemModel()
        node1 = QStandardItem('node1')
        self._node1_1 = QStandardItem('node1_1')
        self._node1_1_1 = QStandardItem('node1_1_1')
        node1_1_2 = QStandardItem('node1_1_2')
        node1_2 = QStandardItem('node1_2')

        node1.appendRow(self._node1_1)
        self._node1_1.appendRow(self._node1_1_1)
        self._node1_1.appendRow(node1_1_2)
        node1.appendRow(node1_2)

        self._model.appendRow(node1)

        # node_list = [node1, node1_1, self._node1_1_1, node1_1_2, node1_2]
        # self._model.appendRow(node_list)

        self._grn_node1_1_1 = '/node1/node1_1/node1_1_1'
        self._len_lower_grn_node1_1 = 2
Esempio n. 34
0
    def _on_ctrl_info(self, index):
        popup = self._popup_widget

        ctrl = self._controllers[index.row()]
        popup.ctrl_name.setText(ctrl.name)
        popup.ctrl_type.setText(ctrl.type)

        res_model = QStandardItemModel()
        model_root = QStandardItem('Claimed Resources')
        res_model.appendRow(model_root)
        for hw_res in ctrl.claimed_resources:
            hw_iface_item = QStandardItem(hw_res.hardware_interface)
            model_root.appendRow(hw_iface_item)
            for res in hw_res.resources:
                res_item = QStandardItem(res)
                hw_iface_item.appendRow(res_item)

        popup.resource_tree.setModel(res_model)
        popup.resource_tree.setItemDelegate(FontDelegate(popup.resource_tree))
        popup.resource_tree.expandAll()
        popup.move(QCursor.pos())
        popup.show()
Esempio n. 35
0
    def _on_ctrl_info(self, index):
        popup = self._popup_widget

        ctrl = self._controllers[index.row()]
        popup.ctrl_name.setText(ctrl.name)
        popup.ctrl_type.setText(ctrl.type)

        res_model = QStandardItemModel()
        model_root = QStandardItem('Claimed Resources')
        res_model.appendRow(model_root)
        for hw_res in ctrl.claimed_resources:
            hw_iface_item = QStandardItem(hw_res.hardware_interface)
            model_root.appendRow(hw_iface_item)
            for res in hw_res.resources:
                res_item = QStandardItem(res)
                hw_iface_item.appendRow(res_item)

        popup.resource_tree.setModel(res_model)
        popup.resource_tree.setItemDelegate(FontDelegate(popup.resource_tree))
        popup.resource_tree.expandAll()
        popup.move(QCursor.pos())
        popup.show()
Esempio n. 36
0
    def _init_monitor_nodes(self, nodes_monitored):
        """
        @type params_monitored: str[]
        @rtype: Thread
        """
        self._node_datamodel = QStandardItemModel(0, 2)
        self._root_qitem = self._node_datamodel.invisibleRootItem()
        self._view_nodes.setModel(self._node_datamodel)

        node_monitor_thread = Thread(target=self._check_nodes_alive,
                                           args=(self.sig_node,
                                                 self._nodes_monitored))
#        self._node_monitor_thread = NodeMonitorThread(self, self.sig_node,
#                                                      nodes_monitored)
        self.sig_node.connect(self._update_output_nodes)
        return node_monitor_thread
Esempio n. 37
0
    def __init__(self, parent):
        '''
        @type parent: LaunchMain
        '''
        super(LaunchWidget, self).__init__()
        self._parent = parent
        print 'FROM WIDGET'

        self._config = None

        #TODO: should be configurable from gui
        self._port_roscore = 11311

        self._run_id = None

        self._rospack = rospkg.RosPack()
        ui_file = os.path.join(self._rospack.get_path('rqt_launch'),
                               'resource', 'launch_widget.ui')
        loadUi(ui_file, self)

        # row=0 allows any number of rows to be added.
        self._datamodel = QStandardItemModel(0, 1)

        master_uri = rosenv.get_master_uri()
        rospy.loginfo('LaunchWidget master_uri={}'.format(master_uri))
        self._delegate = NodeDelegate(master_uri,
                                      self._rospack)
        self._treeview.setModel(self._datamodel)
        self._treeview.setItemDelegate(self._delegate)

        # NodeController used in controller class for launch operation.
        self._node_controllers = []

        self._pushbutton_start_all.clicked.connect(self._parent.start_all)
        self._pushbutton_stop_all.clicked.connect(self._parent.stop_all)
        # Bind package selection with .launch file selection.
        self._combobox_pkg.currentIndexChanged[str].connect(
                                                 self._refresh_launchfiles)
        # Bind a launch file selection with launch GUI generation.
        self._combobox_launchfile_name.currentIndexChanged[str].connect(
                                                 self._load_launchfile_slot)
        self._update_pkgs_contain_launchfiles()

        # Used for removing previous nodes
        self._num_nodes_previous = 0
    def setUp(self):
        unittest.TestCase.setUp(self)

        self._model = QStandardItemModel()
        node1 = QStandardItem('node1')
        self._node1_1 = QStandardItem('node1_1')
        self._node1_1_1 = QStandardItem('node1_1_1')
        node1_1_2 = QStandardItem('node1_1_2')
        node1_2 = QStandardItem('node1_2')

        node1.appendRow(self._node1_1)
        self._node1_1.appendRow(self._node1_1_1)
        self._node1_1.appendRow(node1_1_2)
        node1.appendRow(node1_2)

        self._model.appendRow(node1)

        #node_list = [node1, node1_1, self._node1_1_1, node1_1_2, node1_2]
        #self._model.appendRow(node_list)

        self._grn_node1_1_1 = '/node1/node1_1/node1_1_1'
        self._len_lower_grn_node1_1 = 2
Esempio n. 39
0
    def _init_monitor_parameters(self, params_monitored,
                                 _col_names_paramtable=None):
        """
        @type params_monitored: str[]
        """
        self._params_monitored = params_monitored

        self._param_datamodel = QStandardItemModel(0, 2)
        self._root_qitem = self._param_datamodel.invisibleRootItem()
        self._view_params.setModel(self._param_datamodel)

        # Names of header on the QTableView.
        if not _col_names_paramtable:
            _col_names_paramtable = ['Param name',
                                     'Found on Parameter Server?']
        self._param_datamodel.setHorizontalHeaderLabels(_col_names_paramtable)

        self.sig_param.connect(self._update_output_parameters)

        param_check_thread = Thread(target=self._check_params_alive,
                                    args=(self.sig_param,
                                          self._params_monitored))
        return param_check_thread
Esempio n. 40
0
    def to_QItemModel(self):
        """
        Represent the DSDs debug data as QITemModel
        """
        # Return cached result if available
        if self.__cached_item_model is not None:
            return self.__cached_item_model

        # Return empty model when no dsd data was received yet
        if self.__cached_msg is None:
            return self.__empty_item_model()

        # Construct a new item-model
        model = QStandardItemModel()
        for i in range(len(self.stack)):
            elem, _ = self.stack[i]
            elem_item = QStandardItem()
            elem_item.setEditable(False)

            if isinstance(elem, SequenceTreeElement):
                elem_item.setText('Sequence: ' + ', '.join(
                    str(e) for e in elem.action_elements))
                sequence = True
            else:
                elem_item.setText(str(elem))
                sequence = False

            self.__append_element_to_item(elem_item, elem.debug_data)

            model.invisibleRootItem().appendRow(elem_item)

            # Add a spacer if this is not the last item
            if elem != self.stack[-1][0]:
                spacer = QStandardItem()
                spacer.setEditable(False)
                model.invisibleRootItem().appendRow(spacer)

            if sequence:
                break

        self.__cached_item_model = model
        return self.__cached_item_model
Esempio n. 41
0
class MoveitWidget(QWidget):
    """#TODO: comment
    """
    # To be connected to PluginContainerWidget
    sig_sysmsg = None
    sig_param = Signal(bool, str)  # param name emitted
    sig_node = Signal(bool, str)  # param name emitted

    _SPLITTER_H = 'splitter_horizontal'

    def __init__(self, parent, plugin_context):
        """
        @type parent: MoveitMain
        """

        self._nodes_monitored = ['/move_group']
        self._selected_topics = [('/pointcloud', 'sensor_msgs/PointCloud'),
                                 ('/pointcloud2', 'sensor_msgs/PointCloud2'),
                                 ('/image', 'sensor_msgs/Image'),
                                 ('/camera_info', 'sensor_msgs/CameraInfo')]
        self._params_monitored = [
            '/robot_description', '/robot_description_semantic'
        ]

        super(MoveitWidget, self).__init__()
        self._parent = parent
        self._plugin_context = plugin_context
        self._refresh_rate = 5  # With default value

        self._rospack = rospkg.RosPack()
        ui_file = os.path.join(self._rospack.get_path('rqt_moveit'),
                               'resource', 'moveit_top.ui')
        loadUi(ui_file, self, {'TopicWidget': TopicWidget})

        # Custom widget classes don't show in QSplitter when they instantiated
        # in .ui file and not explicitly added to QSplitter like this. Thus
        # this is a workaround.
        self._splitter.addWidget(self._widget_topic)

        self._spinbox_refreshrate.valueChanged.connect(
            self._update_refreshrate)
        # Show default ref rate on QSpinbox
        self._spinbox_refreshrate.setValue(self._refresh_rate)

        # Monitor node
        self._is_checking_nodes = True
        self._node_qitems = {}
        self._node_monitor_thread = self._init_monitor_nodes(
            self._nodes_monitored)
        self._node_monitor_thread.start()
        #TODO: connect sys msg for nodes.

        # topic to show
        # Delegate GUI functionality to rqt_topic.TopicWidget.
        self._widget_topic.set_selected_topics(self._selected_topics)
        self._widget_topic.set_topic_specifier(TopicWidget.SELECT_BY_MSGTYPE)
        self._widget_topic.start()
        # To connect signal in a widget to PluginContainerWidget.
        #TODO: In this way, Signal from only one instance is hooked.
        # Not a good design at all.
        self.sig_sysmsg = self._widget_topic.sig_sysmsg

        # Init monitoring parameters.
        self._is_checking_params = True
        self._param_qitems = {}
        _col_names_paramtable = ['Param name', 'Found on Parameter Server?']
        self._param_check_thread = self._init_monitor_parameters(
            self._params_monitored, _col_names_paramtable)
        self._param_check_thread.start()

    def _init_monitor_nodes(self, nodes_monitored):
        """
        @type params_monitored: str[]
        @rtype: Thread
        """
        self._node_datamodel = QStandardItemModel(0, 2)
        self._root_qitem = self._node_datamodel.invisibleRootItem()
        self._view_nodes.setModel(self._node_datamodel)

        node_monitor_thread = Thread(target=self._check_nodes_alive,
                                     args=(self.sig_node,
                                           self._nodes_monitored))
        #        self._node_monitor_thread = NodeMonitorThread(self, self.sig_node,
        #                                                      nodes_monitored)
        self.sig_node.connect(self._update_output_nodes)
        return node_monitor_thread

    def _check_nodes_alive(self, signal, nodes_monitored):
        """
        Working as a callback of Thread class, this method keeps looping to
        watch if the nodes whose names are passed exist and emits signal per
        each node.

        Notice that what MoveitWidget._check_nodes_alive &
        MoveitWidget._check_params_alive do is very similar, but since both of
        them are supposed to be passed to Thread class, there might not be
        a way to generalize these 2.

        @param signal: Signal(bool, str)
        @type nodes_monitored: str[]
        """
        while self._is_checking_nodes:
            rosnode_dynamically_loaded = __import__('rosnode')
            #from rosnode import rosnode_ping
            for nodename in nodes_monitored:
                #TODO: rosnode_ping prints when the node is not found.
                # Currently I have no idea how to capture that from here.
                try:
                    #is_node_running = rosnode_ping(nodename, 1)
                    is_node_running = rosnode_dynamically_loaded.rosnode_ping(
                        nodename, 1)
                except rosnode_dynamically_loaded.ROSNodeIOException as e:
                    #TODO: Needs to be indicated on GUI
                    #      (eg. PluginContainerWidget)
                    rospy.logerr(e.message)
                    is_node_running = False

                signal.emit(is_node_running, nodename)
                rospy.logdebug('_update_output_nodes')
            del rosnode_dynamically_loaded
            time.sleep(self._refresh_rate)

    def _init_monitor_parameters(self,
                                 params_monitored,
                                 _col_names_paramtable=None):
        """
        @type params_monitored: str[]
        """
        self._params_monitored = params_monitored

        self._param_datamodel = QStandardItemModel(0, 2)
        self._root_qitem = self._param_datamodel.invisibleRootItem()
        self._view_params.setModel(self._param_datamodel)

        # Names of header on the QTableView.
        if not _col_names_paramtable:
            _col_names_paramtable = [
                'Param name', 'Found on Parameter Server?'
            ]
        self._param_datamodel.setHorizontalHeaderLabels(_col_names_paramtable)

        self.sig_param.connect(self._update_output_parameters)

        param_check_thread = Thread(target=self._check_params_alive,
                                    args=(self.sig_param,
                                          self._params_monitored))
        return param_check_thread

    def _update_output_nodes(self, is_node_running, node_name):
        """
        Slot for signals that tell nodes existence.

        @type is_node_running: bool
        @type node_name: str
        """
        #TODO: What this method does is exactly the same with
        # monitor_parameters. Unify them.

        rospy.logdebug('is_node_running={} par_name={}'.format(
            is_node_running, node_name))
        node_name = str(node_name)
        node_qitem = None
        if not node_name in self._node_qitems:
            node_qitem = QStandardItem(node_name)
            self._node_qitems[node_name] = node_qitem
            self._node_datamodel.appendRow(node_qitem)
        else:  # qsitem with the node name already exists.
            node_qitem = self._node_qitems[str(node_name)]

        qindex = self._node_datamodel.indexFromItem(node_qitem)
        _str_node_running = 'Not running'
        if is_node_running:
            _str_node_running = 'Running'
        qitem_node_status = QStandardItem(_str_node_running)
        self._node_datamodel.setItem(qindex.row(), 1, qitem_node_status)

    def _check_params_alive(self, signal, params_monitored):
        """
        Working as a callback of Thread class, this method keeps looping to
        watch if the params whose names are passed exist and emits signal per
        each node.

        Notice that what MoveitWidget._check_nodes_alive &
        MoveitWidget._check_params_alive do is very similar, but since both of
        them are supposed to be passed to Thread class, there might not be
        a way to generalize these 2.

        @type signal: Signal(bool, str)
        @param_name signal: emitting a name of the parameter that's found.
        @type params_monitored: str[]
        """

        while self._is_checking_params:
            # self._is_checking_params only turns to false when the plugin
            # shuts down.

            has_param = False

            for param_name in params_monitored:
                is_rosmaster_running = RqtRoscommUtil.is_roscore_running()

                try:
                    if is_rosmaster_running:
                        # Only if rosmaster is running, check if the parameter
                        # exists or not.
                        has_param = rospy.has_param(param_name)
                except rospy.exceptions.ROSException as e:
                    self.sig_sysmsg.emit(
                        'Exception upon rospy.has_param {}'.format(e.message))
                signal.emit(has_param, param_name)
                rospy.loginfo('has_param {}, check_param_alive: {}'.format(
                    has_param, param_name))
            time.sleep(self._refresh_rate)

    def _update_output_parameters(self, has_param, param_name):
        """
        Slot

        @type has_param: bool
        @type param_name: str
        """
        rospy.logdebug('has_param={} par_name={}'.format(
            has_param, param_name))
        param_name = str(param_name)
        param_qitem = None
        if not param_name in self._param_qitems:
            param_qitem = QStandardItem(param_name)
            self._param_qitems[param_name] = param_qitem
            self._param_datamodel.appendRow(param_qitem)
        else:  # qsitem with the param name already exists.
            param_qitem = self._param_qitems[str(param_name)]

        qindex = self._param_datamodel.indexFromItem(param_qitem)
        _str_param_found = 'No'
        if has_param:
            _str_param_found = 'Yes'
        qitem_param_status = QStandardItem(_str_param_found)
        self._param_datamodel.setItem(qindex.row(), 1, qitem_param_status)
        self._view_params.resizeColumnsToContents()

    def _update_refreshrate(self, refresh_rate):
        """
        Slot

        @type refresh_rate: int
        """
        self._refresh_rate = refresh_rate

    def save_settings(self, plugin_settings, instance_settings):
        instance_settings.set_value(self._SPLITTER_H,
                                    self._splitter.saveState())

    def restore_settings(self, plugin_settings, instance_settings):
        if instance_settings.contains(self._SPLITTER_H):
            self._splitter.restoreState(
                instance_settings.value(self._SPLITTER_H))
        else:
            self._splitter.setSizes([100, 100, 200])
        pass

    def shutdown(self):
        """
        Overridden.

        Close threads.

        @raise RuntimeError:
        """
        try:
            #self._node_monitor_thread.join()  # No effect
            self._is_checking_nodes = False
            self._node_monitor_thread = None
            #self._param_check_thread.join()

            self._is_checking_params = False
            self._param_check_thread = None
        except RuntimeError as e:
            rospy.logerr(e)
            raise e
class LaunchWidget(QDialog):
    '''#TODO: comment
    '''

    # To be connected to PluginContainerWidget
    sig_sysmsg = Signal(str)

    def __init__(self, parent):
        '''
        @type parent: LaunchMain
        '''
        super(LaunchWidget, self).__init__()
        self._parent = parent

        self._config = None

        #TODO: should be configurable from gui
        self._port_roscore = 11311

        self._run_id = None

        self._rospack = rospkg.RosPack()
        ui_file = os.path.join(self._rospack.get_path('rqt_launch'),
                               'resource', 'launch_widget.ui')
        loadUi(ui_file, self)

        # row=0 allows any number of rows to be added.
        self._datamodel = QStandardItemModel(0, 1)

        master_uri = rosenv.get_master_uri()
        rospy.loginfo('LaunchWidget master_uri={}'.format(master_uri))
        self._delegate = NodeDelegate(master_uri, self._rospack)
        self._treeview.setModel(self._datamodel)
        self._treeview.setItemDelegate(self._delegate)

        # NodeController used in controller class for launch operation.
        self._node_controllers = []

        self._pushbutton_start_all.clicked.connect(self._parent.start_all)
        self._pushbutton_stop_all.clicked.connect(self._parent.stop_all)
        # Bind package selection with .launch file selection.
        self._combobox_pkg.currentIndexChanged[str].connect(
            self._refresh_launchfiles)
        # Bind a launch file selection with launch GUI generation.
        self._combobox_launchfile_name.currentIndexChanged[str].connect(
            self._load_launchfile_slot)
        self._update_pkgs_contain_launchfiles()

        # Used for removing previous nodes
        self._num_nodes_previous = 0

    def _load_launchfile_slot(self, launchfile_name):
        # Not yet sure why, but everytime combobox.currentIndexChanged occurs,
        # this method gets called twice with launchfile_name=='' in 1st call.
        if launchfile_name == None or launchfile_name == '':
            return

        _config = None

        rospy.logdebug(
            '_load_launchfile_slot launchfile_name={}'.format(launchfile_name))

        try:
            _config = self._create_launchconfig(launchfile_name,
                                                self._port_roscore)
            #TODO: folder_name_launchfile should be able to specify arbitrarily
            # _create_launchconfig takes 3rd arg for it.

        except IndexError as e:
            msg = 'IndexError={} launchfile={}'.format(e.message,
                                                       launchfile_name)
            rospy.logerr(msg)
            self.sig_sysmsg.emit(msg)
            return
        except RLException as e:
            msg = 'RLException={} launchfile={}'.format(
                e.message, launchfile_name)
            rospy.logerr(msg)
            self.sig_sysmsg.emit(msg)
            return

        self._create_widgets_for_launchfile(_config)

    def _create_launchconfig(self,
                             launchfile_name,
                             port_roscore=11311,
                             folder_name_launchfile='launch'):
        '''
        @rtype: ROSLaunchConfig
        @raises RLException: raised by roslaunch.config.load_config_default.
        '''

        pkg_name = self._combobox_pkg.currentText()

        try:
            launchfile = os.path.join(self._rospack.get_path(pkg_name),
                                      folder_name_launchfile, launchfile_name)
        except IndexError as e:
            raise RLException('IndexError: {}'.format(e.message))

        try:
            launch_config = roslaunch.config.load_config_default([launchfile],
                                                                 port_roscore)
        except rospkg.common.ResourceNotFound as e:
            raise RLException('ResourceNotFound: {}'.format(e.message))
        except RLException as e:
            raise e

        return launch_config

    def _create_widgets_for_launchfile(self, config):
        self._config = config

        # Delete old nodes' GUIs.
        self._node_controllers = []

        # These lines seem to remove indexWidgets previously set on treeview.
        # Per suggestion in API doc, we are not using reset(). Instead,
        # using 2 methods below without any operation in between, which
        # I suspect might be inproper.
        # http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#reset
        self._datamodel.beginResetModel()
        self._datamodel.endResetModel()

        # Need to store the num of nodes outside of the loop -- this will
        # be used for removing excessive previous node rows.
        order_xmlelement = 0
        # Loop per xml element
        for order_xmlelement, node in enumerate(self._config.nodes):
            proxy = NodeProxy(self._run_id, self._config.master.uri, node)

            # TODO: consider using QIcon.fromTheme()
            status_label = StatusIndicator()

            qindex_nodewidget = self._datamodel.index(order_xmlelement, 0,
                                                      QModelIndex())
            node_widget = self._delegate.create_node_widget(
                qindex_nodewidget, proxy.config, status_label)

            #TODO: Ideally find a way so that we don't need this block.
            #BEGIN If these lines are missing, widget won't be shown either.
            std_item = QStandardItem(
                #node_widget.get_node_name()
            )
            self._datamodel.setItem(order_xmlelement, 0, std_item)
            #END If these lines are missing, widget won't be shown either.

            self._treeview.setIndexWidget(qindex_nodewidget, node_widget)

            node_controller = NodeController(proxy, node_widget)
            self._node_controllers.append(node_controller)

            node_widget.connect_start_stop_button( \
                                       node_controller.start_stop_slot)
            rospy.logdebug(
                'loop #%d proxy.config.namespace=%s ' + 'proxy.config.name=%s',
                order_xmlelement, proxy.config.namespace, proxy.config.name)

        self._num_nodes_previous = order_xmlelement

        self._parent.set_node_controllers(self._node_controllers)

    def _update_pkgs_contain_launchfiles(self):
        '''
        Inspired by rqt_msg.MessageWidget._update_pkgs_contain_launchfiles
        '''
        packages = sorted([
            pkg_tuple[0]
            for pkg_tuple in RqtRoscommUtil.iterate_packages('launch')
        ])
        self._package_list = packages
        rospy.logdebug('pkgs={}'.format(self._package_list))
        self._combobox_pkg.clear()
        self._combobox_pkg.addItems(self._package_list)
        self._combobox_pkg.setCurrentIndex(0)

    def _refresh_launchfiles(self, package=None):
        '''
        Inspired by rqt_msg.MessageWidget._refresh_msgs
        '''
        if package is None or len(package) == 0:
            return
        self._launchfile_instances = []  # Launch[]
        #TODO: RqtRoscommUtil.list_files's 2nd arg 'subdir' should NOT be
        # hardcoded later.
        _launch_instance_list = RqtRoscommUtil.list_files(package, 'launch')

        rospy.logdebug('_refresh_launches package={} instance_list={}'.format(
            package, _launch_instance_list))

        self._launchfile_instances = [
            x.split('/')[1] for x in _launch_instance_list
        ]

        self._combobox_launchfile_name.clear()
        self._combobox_launchfile_name.addItems(self._launchfile_instances)

    def save_settings(self, plugin_settings, instance_settings):
        # instance_settings.set_value('splitter', self._splitter.saveState())
        pass

    def restore_settings(self, plugin_settings, instance_settings):
        #        if instance_settings.contains('splitter'):
        #            self._splitter.restoreState(instance_settings.value('splitter'))
        #        else:
        #            self._splitter.setSizes([100, 100, 200])
        pass
Esempio n. 43
0
    def __init__(self, context):
        super(Conman, self).__init__(context)

        self._dotcode_sub = None

        # Give QObjects reasonable names
        self.setObjectName('Conman')

        # Process standalone plugin command-line arguments
        from argparse import ArgumentParser
        parser = ArgumentParser()
        # Add argument(s) to the parser.
        parser.add_argument("-q", "--quiet", action="store_true",
                      dest="quiet",
                      help="Put plugin in silent mode")
        args, unknowns = parser.parse_known_args(context.argv())
        if not args.quiet:
            print 'arguments: ', args
            print 'unknowns: ', unknowns

        # Create QWidget
        self._widget = QWidget()
        # Get path to UI file which is a sibling of this file
        # in this example the .ui and .py file are in the same folder
        ui_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'rqt_conman.ui')
        # Extend the widget with all attributes and children from UI file
        loadUi(ui_file, self._widget)
        # Give QObjects reasonable names

        self._widget.setObjectName('ConmanPluginUi')
        # Show _widget.windowTitle on left-top of each plugin (when 
        # it's set in _widget). This is useful when you open multiple 
        # plugins at once. Also if you open multiple instances of your 
        # plugin at once, these lines add number to make it easy to 
        # tell from pane to pane.
        if context.serial_number() > 1:
            self._widget.setWindowTitle(self._widget.windowTitle() + (' (%d)' % context.serial_number()))

        # Add widget to the user interface
        context.add_widget(self._widget)
        palette = QPalette ()
        palette.setColor(QPalette.Background, Qt.white)
        self._widget.setPalette(palette)

        #self._widget.subscribe_button.setCheckable(True)

        self._widget.refresh_button.clicked[bool].connect(self._handle_refresh_clicked)
        self._widget.commit_button.clicked[bool].connect(self._handle_commit_clicked)

        #self._widget.xdot_widget.connect(
                #self._widget.xdot_widget, SIGNAL('_update_graph'), self._widget.xdot_widget.set_dotcode)
        self.update_graph_sig.connect(self._update_graph)

        self.blocks = { }
        self.groups = { }

        self._ns = ""
        self._actions_connected = False
        self.enable_widgets(False)
        self.new_dotcode_data = ''

        self.update_timer = QTimer(self)
        self.update_timer.setInterval(50)
        self.update_timer.timeout.connect(self._update_widgets)
        #self.update_timer.start()


        self._get_blocks = None
        self._set_blocks = None

        self._blocks_model = QStandardItemModel(0,4)
        self._blocks_model.setHeaderData(0, Qt.Horizontal, "")
        self._blocks_model.setHeaderData(1, Qt.Horizontal, "Action")
        self._blocks_model.setHeaderData(2, Qt.Horizontal, "State")
        self._blocks_model.setHeaderData(3, Qt.Horizontal, "Block")
        self._widget.blocks_table.setModel(self._blocks_model)
        self._blocks_delegate = BlocksDelegate(self)
        self._widget.blocks_table.setItemDelegate(self._blocks_delegate)
        self._blocks_model.itemChanged.connect(self.block_changed)

        self._groups_model = QStandardItemModel(0,4)
        self._groups_model.setHeaderData(0, Qt.Horizontal, "")
        self._groups_model.setHeaderData(1, Qt.Horizontal, "")
        self._groups_model.setHeaderData(2, Qt.Horizontal, "")
        self._groups_model.setHeaderData(3, Qt.Horizontal, "Group")
        self._widget.groups_table.setModel(self._groups_model)
        self._groups_delegate = GroupsDelegate(self)
        self._widget.groups_table.setItemDelegate(self._groups_delegate)
Esempio n. 44
0
class RqtSrVisualServoing(Plugin):

    def __init__(self, context):
        super(RqtSrVisualServoing, self).__init__(context)
        # Give QObjects reasonable names
        self.setObjectName('RqtSrVisualServoing')

        # # Process standalone plugin command-line arguments
        # from argparse import ArgumentParser
        # parser = ArgumentParser()
        # # Add argument(s) to the parser.
        # parser.add_argument("-q", "--quiet", action="store_true",
        #               dest="quiet",
        #               help="Put plugin in silent mode")
        # args, unknowns = parser.parse_known_args(context.argv())
        # if not args.quiet:
        #     print 'arguments: ', args
        #     print 'unknowns: ', unknowns

        # Create QWidget
        self.ui = QWidget()
        # Get path to UI file which is in our packages resource directory
        rp = rospkg.RosPack()
        self.ui_file = os.path.join(rp.get_path(PKG), 'resource', 'gui.ui')
        # Extend the widget with all attributes and children from UI file
        loadUi(self.ui_file, self.ui)
        # Give QObjects reasonable names
        self.ui.setObjectName('RqtSrVisualServoingUi')
        # Show ui.windowTitle on left-top of each plugin (when it's set in ui).
        # This is useful when you open multiple plugins at once. Also if you
        # open multiple instances of your plugin at once, these lines add
        # number to make it easy to tell from pane to pane.
        if context.serial_number() > 1:
            self.ui.setWindowTitle(self.ui.windowTitle() + (' (%d)' % context.serial_number()))

        # Wire up the buttons
        self.ui.startBtn.clicked.connect( self.start_clicked )
        self.ui.stopBtn.clicked.connect( self.stop_clicked )

        # Annoyingly setting the icon theme in designer only works in designer,
        # we have to set it again here for it to work at run time
        self.ui.startBtn.setIcon(QIcon.fromTheme('media-playback-start'))
        self.ui.stopBtn.setIcon(QIcon.fromTheme('media-playback-stop'))

        # Add widget to the user interface
        context.add_widget(self.ui)

        # Setup a model for the feedback and link to the view.
        self.feedback_model = QStandardItemModel(0,2)
        self.feedback_model.setHorizontalHeaderLabels(['Name','Value'])
        self.ui.feedbackView.setModel(self.feedback_model)
        self.ui.connect( self.ui, SIGNAL('feedback(QString)'), self.update_feedback )

        # ROS setup
        self.last_feedback = None
        self.client = actionlib.SimpleActionClient('visual_servo', VisualServoingAction)
        msg = ""
        if self.client.wait_for_server(rospy.Duration(2.0)):
            msg = "Found action server, servoing appears to be running"
            rospy.loginfo(msg)
        else:
            msg = "Can't find action server, servoing not running"
            rospy.logerr(msg)
        self.ui.statusValue.setText(msg)

    def shutdown_plugin(self):
        # TODO unregister all publishers here
        pass

    def save_settings(self, plugin_settings, instance_settings):
        # TODO save intrinsic configuration, usually using:
        # instance_settings.set_value(k, v)
        pass

    def restore_settings(self, plugin_settings, instance_settings):
        # TODO restore intrinsic configuration, usually using:
        # v = instance_settings.value(k)
        pass

    #def trigger_configuration(self):
        # Comment in to signal that the plugin has a way to configure it
        # Usually used to open a configuration dialog

    def start_clicked(self):
        goal = VisualServoingActionGoal()
        self.client.send_goal(goal, feedback_cb = self._feedback_cb)
        self.ui.statusValue.setText("Starting")

    def stop_clicked(self):
        self.client.cancel_all_goals()
        self.ui.statusValue.setText("Stopped")
        self.feedback_model.clear()

    def _feedback_cb(self, feedback):
        # We can't update the UI in this thread so stash the data and emit a
        # signal that can be traped by the main thread and update the ui.
        self.last_feedback = feedback
        self.ui.emit( SIGNAL('feedback(QString)'), "" )

    def update_feedback(self, data):
        """Listen for feedback signals and update the interface."""
        fb = self.last_feedback
        self.ui.statusValue.setText(str(self.client.get_goal_status_text()))

        # Update the feedback model, which triggers the view to update
        m = self.feedback_model
        m.setHorizontalHeaderLabels(['Name','Value'])

        m.setItem(0,0,QStandardItem('distance'))
        m.setItem(0,1,QStandardItem(str(fb.distance)))

        m.setItem(1,0,QStandardItem('object_pose.position.x'))
        m.setItem(1,1,QStandardItem(str(fb.object_pose.position.x)))
        m.setItem(2,0,QStandardItem('object_pose.position.y'))
        m.setItem(2,1,QStandardItem(str(fb.object_pose.position.y)))
        m.setItem(3,0,QStandardItem('object_pose.position.z'))
        m.setItem(3,1,QStandardItem(str(fb.object_pose.position.z)))

        m.setItem(4,0,QStandardItem('object_pose.orientation.x'))
        m.setItem(4,1,QStandardItem(str(fb.object_pose.orientation.x)))
        m.setItem(5,0,QStandardItem('object_pose.orientation.y'))
        m.setItem(5,1,QStandardItem(str(fb.object_pose.orientation.y)))
        m.setItem(6,0,QStandardItem('object_pose.orientation.z'))
        m.setItem(6,1,QStandardItem(str(fb.object_pose.orientation.z)))
        m.setItem(7,0,QStandardItem('object_pose.orientation.w'))
        m.setItem(7,1,QStandardItem(str(fb.object_pose.orientation.w)))

        m.setItem(8,0,QStandardItem('grasp_pose.position.x'))
        m.setItem(8,1,QStandardItem(str(fb.grasp_pose.position.x)))
        m.setItem(9,0,QStandardItem('grasp_pose.position.y'))
        m.setItem(9,1,QStandardItem(str(fb.grasp_pose.position.y)))
        m.setItem(10,0,QStandardItem('grasp_pose.position.z'))
        m.setItem(10,1,QStandardItem(str(fb.grasp_pose.position.z)))

        m.setItem(11,0,QStandardItem('grasp_pose.orientation.x'))
        m.setItem(11,1,QStandardItem(str(fb.grasp_pose.orientation.x)))
        m.setItem(12,0,QStandardItem('grasp_pose.orientation.y'))
        m.setItem(12,1,QStandardItem(str(fb.grasp_pose.orientation.y)))
        m.setItem(13,0,QStandardItem('grasp_pose.orientation.z'))
        m.setItem(13,1,QStandardItem(str(fb.grasp_pose.orientation.z)))
        m.setItem(14,0,QStandardItem('grasp_pose.orientation.w'))
        m.setItem(14,1,QStandardItem(str(fb.grasp_pose.orientation.w)))

        self.ui.feedbackView.resizeColumnsToContents()
Esempio n. 45
0
class QtRappManager(Plugin):
    _update_rapps_signal = Signal()

    def __init__(self, context):
        self._context = context
        super(QtRappManager, self).__init__(context)

        self._init_ui(context)
        self._init_events()
        self._init_variables()
        self.spin()

    def _init_ui(self, context):
        self._widget = QWidget()
        self.setObjectName('QtRappManger')

        rospack = rospkg.RosPack()
        ui_file = os.path.join(rospack.get_path('rocon_qt_app_manager'), 'ui',
                               'qt_rapp_manager.ui')
        self._widget.setObjectName('QtRappManger')
        loadUi(ui_file, self._widget, {})

        if context.serial_number() > 1:
            self._widget.setWindowTitle(self._widget.windowTitle() +
                                        (' (%d)' % context.serial_number()))
        context.add_widget(self._widget)

        # Set view mode
        self._widget.rapp_grid.setViewMode(QListView.IconMode)
        #self._widget.rapp_grid.setViewMode(QListView.ListMode)

    def _init_events(self):
        #combo box change event
        self._widget.namespace_cbox.currentIndexChanged.connect(
            self._change_namespace)

        # Rapp single click event
        self._widget.rapp_grid.clicked.connect(self._rapp_single_click)
        # Rapp double click event
        self._widget.rapp_grid.doubleClicked.connect(self._rapp_double_click)

    def _init_variables(self):
        self.initialised = False

        #init
        self._qt_rapp_manager_info = QtRappManagerInfo(self._refresh_rapps)
        self._update_rapps_signal.connect(self._update_rapp_list)

        self._rapp_view_model = QStandardItemModel()
        self._widget.rapp_grid.setModel(self._rapp_view_model)
        self._widget.rapp_grid.setWrapping(True)
        self._widget.rapp_grid.setIconSize(QSize(60, 60))
        self._widget.rapp_grid.setSpacing(10)

        self._selected_rapp = None

    def spin(self):
        self._get_appmanager_namespaces()

    def _cleanup_rapps(self):
        self._rapp_view_model.clear()
        pass

    def _get_appmanager_namespaces(self):
        namespaces = self._qt_rapp_manager_info._get_namespaces()
        for namespace in namespaces:
            ns = namespace[:namespace.find('list_rapps')]
            self._widget.namespace_cbox.addItem(ns)

    def _exit(self):
        pass

###################################################################
# Events
###################################################################

    def _change_namespace(self, event):
        self._qt_rapp_manager_info.select_rapp_manager(
            self._widget.namespace_cbox.currentText())

    def _refresh_rapps(self):
        """
        Updates from qt_app_manager_info.
        """
        self._update_rapps_signal.emit()

    def _update_rapp_list(self):
        """
        Rapp manager namespace event
        """
        self._cleanup_rapps()
        available_rapps = self._qt_rapp_manager_info.get_available_rapps()
        running_rapps = self._qt_rapp_manager_info.get_running_rapps()

        rapp_items = []
        for r, v in available_rapps.items():
            if r in running_rapps.keys():
                item = QRappItem(v, running=True)
            else:
                item = QRappItem(v, running=False)
            self._rapp_view_model.appendRow(item)

    def _rapp_single_click(self, index):
        qrapp = self._rapp_view_model.item(index.row())
        rapp = qrapp.getRapp()
        self._create_rapp_dialog(rapp)

    def _create_rapp_dialog(self, rapp):
        is_running = self._qt_rapp_manager_info.is_running_rapp(rapp)
        self._selected_rapp = rapp
        self._dialog = QtRappDialog(self._widget, rapp,
                                    self._qt_rapp_manager_info.start_rapp,
                                    self._qt_rapp_manager_info.stop_rapp,
                                    is_running)
        self._dialog.show()

    def _rapp_double_click(self, item):
        running_rapps = self._qt_rapp_manager_info.get_running_rapps()
        if len(running_rapps) > 0:
            names = [r['display_name'] for r in running_rapps.values()]
            show_message(self._widget, "Error",
                         "Rapp %s are already running" % names)
        else:
            self._start_rapp()

    def _start_rapp(self):
        result = self._qt_rapp_manager_info.start_rapp(
            self._selected_rapp['name'], [],
            self._selected_rapp['public_parameters'])
        show_message(self._widget, str(result.started), result.message)
        self._selected_rapp = None
        return result

    def _stop_rapp(self):
        result = self._qt_rapp_manager_info.stop_rapp()
        show_message(self._widget, str(result.stopped), result.message)
        self._selected_rapp = None
        return result

########################################
# Legacy
########################################

    def _select_rapp_tree_item(self, item):
        if not item in self.rapps.keys():
            print "HAS NO KEY"
        else:
            self.current_rapp = self.rapps[item]
        self._widget.rapp_info_text.clear()
        rapp_info = self.qt_rapp_manager_info._get_rapp_info(self.current_rapp)
        self._widget.rapp_info_text.appendHtml(rapp_info)
        self._update_rapp_parameter_layout(self.current_rapp)
        self._update_implementation_tree(self.current_rapp)

    def _update_rapp_parameter_layout(self, rapp):
        parameters_layout = self._widget.rapp_parameter_layout
        clear_layout(parameters_layout)

        for param in rapp['public_parameters']:
            one_param_layout = create_label_textedit_pair(
                param.key, param.value)
            parameters_layout.addLayout(one_param_layout)

    def _update_implementation_tree(self, rapp):
        self._widget.implementation_tree_widget.clear()
        self.selected_impl = None
        self.impls = {}
        for impl in rapp['implementations']:
            impl_item = QTreeWidgetItem(
                self._widget.implementation_tree_widget)
            impl_item.setText(0, impl)
            self.impls[impl_item] = impl

    def _select_implementation_tree_item(self, item):
        if not item in self.impls.keys():
            print "HAS NO KEY"
        else:
            self.selected_impl = self.impls[item]

    def _get_public_parameters(self):
        public_parameters = {}
        parameters_layout = self._widget.rapp_parameter_layout
        for i in reversed(range(parameters_layout.count())):
            item = parameters_layout.itemAt(i)
            key_label = item.itemAt(0).widget()
            value_textbox = item.itemAt(1).widget()
            public_parameters[key_label.text()] = str(
                value_textbox.toPlainText())
        return public_parameters
Esempio n. 46
0
    def __init__(self, context):
        super(RqtSrVisualServoing, self).__init__(context)
        # Give QObjects reasonable names
        self.setObjectName('RqtSrVisualServoing')

        # # Process standalone plugin command-line arguments
        # from argparse import ArgumentParser
        # parser = ArgumentParser()
        # # Add argument(s) to the parser.
        # parser.add_argument("-q", "--quiet", action="store_true",
        #               dest="quiet",
        #               help="Put plugin in silent mode")
        # args, unknowns = parser.parse_known_args(context.argv())
        # if not args.quiet:
        #     print 'arguments: ', args
        #     print 'unknowns: ', unknowns

        # Create QWidget
        self.ui = QWidget()
        # Get path to UI file which is in our packages resource directory
        rp = rospkg.RosPack()
        self.ui_file = os.path.join(rp.get_path(PKG), 'resource', 'gui.ui')
        # Extend the widget with all attributes and children from UI file
        loadUi(self.ui_file, self.ui)
        # Give QObjects reasonable names
        self.ui.setObjectName('RqtSrVisualServoingUi')
        # Show ui.windowTitle on left-top of each plugin (when it's set in ui).
        # This is useful when you open multiple plugins at once. Also if you
        # open multiple instances of your plugin at once, these lines add
        # number to make it easy to tell from pane to pane.
        if context.serial_number() > 1:
            self.ui.setWindowTitle(self.ui.windowTitle() + (' (%d)' % context.serial_number()))

        # Wire up the buttons
        self.ui.startBtn.clicked.connect( self.start_clicked )
        self.ui.stopBtn.clicked.connect( self.stop_clicked )

        # Annoyingly setting the icon theme in designer only works in designer,
        # we have to set it again here for it to work at run time
        self.ui.startBtn.setIcon(QIcon.fromTheme('media-playback-start'))
        self.ui.stopBtn.setIcon(QIcon.fromTheme('media-playback-stop'))

        # Add widget to the user interface
        context.add_widget(self.ui)

        # Setup a model for the feedback and link to the view.
        self.feedback_model = QStandardItemModel(0,2)
        self.feedback_model.setHorizontalHeaderLabels(['Name','Value'])
        self.ui.feedbackView.setModel(self.feedback_model)
        self.ui.connect( self.ui, SIGNAL('feedback(QString)'), self.update_feedback )

        # ROS setup
        self.last_feedback = None
        self.client = actionlib.SimpleActionClient('visual_servo', VisualServoingAction)
        msg = ""
        if self.client.wait_for_server(rospy.Duration(2.0)):
            msg = "Found action server, servoing appears to be running"
            rospy.loginfo(msg)
        else:
            msg = "Can't find action server, servoing not running"
            rospy.logerr(msg)
        self.ui.statusValue.setText(msg)
Esempio n. 47
0
class Conman(Plugin):
    update_graph_sig = Signal(str)

    def __init__(self, context):
        super(Conman, self).__init__(context)

        self._dotcode_sub = None

        # Give QObjects reasonable names
        self.setObjectName('Conman')

        # Process standalone plugin command-line arguments
        from argparse import ArgumentParser
        parser = ArgumentParser()
        # Add argument(s) to the parser.
        parser.add_argument("-q", "--quiet", action="store_true",
                      dest="quiet",
                      help="Put plugin in silent mode")
        args, unknowns = parser.parse_known_args(context.argv())
        if not args.quiet:
            print 'arguments: ', args
            print 'unknowns: ', unknowns

        # Create QWidget
        self._widget = QWidget()
        # Get path to UI file which is a sibling of this file
        # in this example the .ui and .py file are in the same folder
        ui_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'rqt_conman.ui')
        # Extend the widget with all attributes and children from UI file
        loadUi(ui_file, self._widget)
        # Give QObjects reasonable names

        self._widget.setObjectName('ConmanPluginUi')
        # Show _widget.windowTitle on left-top of each plugin (when 
        # it's set in _widget). This is useful when you open multiple 
        # plugins at once. Also if you open multiple instances of your 
        # plugin at once, these lines add number to make it easy to 
        # tell from pane to pane.
        if context.serial_number() > 1:
            self._widget.setWindowTitle(self._widget.windowTitle() + (' (%d)' % context.serial_number()))

        # Add widget to the user interface
        context.add_widget(self._widget)
        palette = QPalette ()
        palette.setColor(QPalette.Background, Qt.white)
        self._widget.setPalette(palette)

        #self._widget.subscribe_button.setCheckable(True)

        self._widget.refresh_button.clicked[bool].connect(self._handle_refresh_clicked)
        self._widget.commit_button.clicked[bool].connect(self._handle_commit_clicked)

        #self._widget.xdot_widget.connect(
                #self._widget.xdot_widget, SIGNAL('_update_graph'), self._widget.xdot_widget.set_dotcode)
        self.update_graph_sig.connect(self._update_graph)

        self.blocks = { }
        self.groups = { }

        self._ns = ""
        self._actions_connected = False
        self.enable_widgets(False)
        self.new_dotcode_data = ''

        self.update_timer = QTimer(self)
        self.update_timer.setInterval(50)
        self.update_timer.timeout.connect(self._update_widgets)
        #self.update_timer.start()


        self._get_blocks = None
        self._set_blocks = None

        self._blocks_model = QStandardItemModel(0,4)
        self._blocks_model.setHeaderData(0, Qt.Horizontal, "")
        self._blocks_model.setHeaderData(1, Qt.Horizontal, "Action")
        self._blocks_model.setHeaderData(2, Qt.Horizontal, "State")
        self._blocks_model.setHeaderData(3, Qt.Horizontal, "Block")
        self._widget.blocks_table.setModel(self._blocks_model)
        self._blocks_delegate = BlocksDelegate(self)
        self._widget.blocks_table.setItemDelegate(self._blocks_delegate)
        self._blocks_model.itemChanged.connect(self.block_changed)

        self._groups_model = QStandardItemModel(0,4)
        self._groups_model.setHeaderData(0, Qt.Horizontal, "")
        self._groups_model.setHeaderData(1, Qt.Horizontal, "")
        self._groups_model.setHeaderData(2, Qt.Horizontal, "")
        self._groups_model.setHeaderData(3, Qt.Horizontal, "Group")
        self._widget.groups_table.setModel(self._groups_model)
        self._groups_delegate = GroupsDelegate(self)
        self._widget.groups_table.setItemDelegate(self._groups_delegate)

    
    def block_changed(self, item):
        row = item.row()
        name = self._blocks_model.item(row,3).text()
        block = self.blocks[name]
        checked = item.checkState() == Qt.Checked

    def shutdown_plugin(self):
        # TODO unregister all publishers here
        pass

    def save_settings(self, plugin_settings, instance_settings):
        # TODO save intrinsic configuration, usually using:
        # instance_settings.set_value(k, v)
        pass

    def restore_settings(self, plugin_settings, instance_settings):
        # TODO restore intrinsic configuration, usually using:
        # v = instance_settings.value(k)
        pass

    #def trigger_configuration(self):
        # Comment in to signal that the plugin has a way to configure
        # This will enable a setting button (gear icon) in each dock widget title bar
        # Usually used to open a modal configuration dialog

    def _get_result_cb(self, status, res):
        rospy.loginfo("got result!")
        self._blocks_model.setRowCount(0)
        self._blocks_model.setRowCount(len(res.blocks))

        for (i,block) in zip(range(len(res.blocks)),res.blocks):

            # Store in dict
            self.blocks[block.name] = block

            cb = QStandardItem(True)
            cb.setCheckable(True)
            cb.setCheckState(Qt.Checked if block.state.value == conman_msgs.msg.TaskState.RUNNING else Qt.Unchecked)
            cb.setTextAlignment(Qt.AlignHCenter)
            cb.setTristate(True)

            action = QStandardItem(True)
            action.setText("")

            state = QStandardItem(True)
            state.setText(state_map[block.state.value])

            name = QStandardItem(True)
            name.setText(str(block.name))

            self._blocks_model.setItem(i,0,cb)
            self._blocks_model.setItem(i,1,action)
            self._blocks_model.setItem(i,2,state)
            self._blocks_model.setItem(i,3,name)

        for (i,group) in zip(range(len(res.groups)),res.groups):

            self.groups[group.name] = group

            cb = QStandardItem(True)
            cb.setCheckable(True)
            cb.setCheckState(Qt.Checked)
            cb.setTextAlignment(Qt.AlignHCenter)
            cb.setEnabled(False)

            name = QStandardItem(True)
            name.setText(str(group.name))

            self._groups_model.setItem(i,0,cb)
            self._groups_model.setItem(i,3,name)

        self._update_groups()
        self._update_blocks()

        self._widget.blocks_table.resizeColumnsToContents()
        self._widget.blocks_table.horizontalHeader().setStretchLastSection(True)
        self._widget.groups_table.resizeColumnsToContents()
        self._widget.groups_table.horizontalHeader().setStretchLastSection(True)

    def _update_blocks(self):
        
        for (name, block) in self.blocks.items():
            items = self._blocks_model.findItems(name, column=3)
            if len(items) > 0:
                item = items[0]
            else:
                continue
            
            row = item.row()
            checked = self._blocks_model.item(row,0).checkState() == Qt.Checked
            if checked and block.state.value != conman_msgs.msg.TaskState.RUNNING:
                self._blocks_model.item(row,1).setText("ENABLE")
            elif not checked and block.state.value == conman_msgs.msg.TaskState.RUNNING:
                self._blocks_model.item(row,1).setText("DISABLE")
            else:
                self._blocks_model.item(row,1).setText("")
        self._update_groups()

    def _enable_group(self, index, enable):
        name = self._groups_model.item(index, 3).text()
        group = self.groups[name]

        for member in group.members:
            items = self._blocks_model.findItems(member, column=3)
            if len(items) > 0:
                item = items[0]
            else:
                continue
            
            row = item.row()
            self._blocks_model.item(row,0).setCheckState(Qt.Checked if enable else Qt.Unchecked)

        self._update_blocks()
        
    def _update_groups(self):
        for (name, group) in self.groups.items():
            group_items = self._groups_model.findItems(name, column=3)
            if len(group_items) > 0:
                group_item = group_items[0]
            else:
                continue
            group_row = group_item.row()

            members_checked = []

            for member in group.members:
                items = self._blocks_model.findItems(member, column=3)
                if len(items) > 0:
                    item = items[0]
                else:
                    continue
                row = item.row()
                members_checked.append(self._blocks_model.item(row,0).checkState() == Qt.Checked)

            if all(members_checked):
                check = Qt.Checked
            else:
                check = Qt.Unchecked

            self._groups_model.item(group_row,0).setCheckState(check)


    def _query_blocks(self):
        if self._get_blocks and self._actions_connected:
            if self._get_blocks.simple_state == actionlib.SimpleGoalState.DONE:
                rospy.loginfo("Getting blocks...")
                goal = conman_msgs.msg.GetBlocksGoal()
                goal.publish_flow_graph = self._widget.generate_graph_checkbox.isChecked()
                self._get_blocks.send_goal(goal, done_cb=self._get_result_cb)


    def enable_widgets(self, enable):
        
        #self._widget.generate_graph_checkbox.setEnabled(enable)
        self._widget.force_enable_checkbox.setEnabled(enable)
        #self._widget.disable_unused_button.setEnabled(enable)
        self._widget.xdot_widget.setEnabled(enable)
        self._widget.blocks_table.setEnabled(enable)
        self._widget.groups_table.setEnabled(enable)
        self._widget.regenerate_graph_button.setEnabled(enable)

    def _handle_refresh_clicked(self, checked):
        ns = self._widget.namespace_input.text()

        if len(ns) > 0:
            if self._ns != ns:
                self._actions_connected = False
                self._ns = ns
                self.enable_widgets(False)

                self._dotcode_sub = rospy.Subscriber(
                        ns+'/dotcode',
                        std_msgs.msg.String,
                        self._dotcode_msg_cb)

                self._get_blocks = actionlib.SimpleActionClient(
                        ns+'/get_blocks_action',
                        conman_msgs.msg.GetBlocksAction)

                self._set_blocks = actionlib.SimpleActionClient(
                        ns+'/set_blocks_action',
                        conman_msgs.msg.SetBlocksAction)

                rospy.loginfo("Creating action clients on namespace '%s'..." % ns)

                if not self._get_blocks.wait_for_server(rospy.Duration(2)):
                    rospy.loginfo("Timed out waiting for %s." % self._get_blocks.action_client.ns)
                    return
                if not self._set_blocks.wait_for_server(rospy.Duration(2)):
                    rospy.loginfo("Timed out waiting for %s." % self._set_blocks.action_client.ns)
                    return

                rospy.loginfo("Action clients created.")
                self._actions_connected = True
                self.enable_widgets(True)

            self._query_blocks()


    def _handle_commit_clicked(self, checked):
        if self._set_blocks and self._actions_connected:
            if self._get_blocks.simple_state == actionlib.SimpleGoalState.DONE:
                rospy.loginfo("Setting blocks...")
                goal = conman_msgs.msg.SetBlocksGoal()
                goal.diff = True
                goal.force = True

                for i in range(self._blocks_model.rowCount()):
                    name = self._blocks_model.item(i,3).text()
                    action = self._blocks_model.item(i,1).text()

                    if action == 'DISABLE':
                        goal.disable.append(name)
                    elif action == 'ENABLE':
                        goal.enable.append(name)

                self._set_blocks.send_goal(goal, done_cb=self._get_set_result_cb)

    def _get_set_result_cb(self, status, res):

        self._query_blocks()

    @Slot(str)
    def _update_graph(self,dotcode):
        self._widget.xdot_widget.set_dotcode(dotcode, center=False)

    def _dotcode_msg_cb(self, msg):
        #self.new_dotcode_data = msg.data
        self.update_graph_sig.emit(msg.data)
    
    def _update_widgets(self):
        self._update_groups()
        self._update_blocks()
Esempio n. 48
0
class MoveitWidget(QWidget):
    """#TODO: comment
    """

    # To be connected to PluginContainerWidget
    sig_sysmsg = None
    sig_param = Signal(bool, str)  # param name emitted
    sig_node = Signal(bool, str)  # param name emitted

    def __init__(self, parent, plugin_context):
        """
        @type parent: MoveitMain
        """

        self._nodes_monitored = ['/move_group']
        self._selected_topics = [('/pointcloud', 'sensor_msgs/PointCloud'),
                                 ('/pointcloud2', 'sensor_msgs/PointCloud2'),
                                 ('/image', 'sensor_msgs/Image'),
                                 ('/camera_info', 'sensor_msgs/CameraInfo')]
        _params_monitored = ['/robot_description',
                             '/robot_description_semantic']

        super(MoveitWidget, self).__init__()
        self._parent = parent
        self._plugin_context = plugin_context

        self._rospack = rospkg.RosPack()
        ui_file = os.path.join(self._rospack.get_path('rqt_moveit'),
                               'resource', 'moveit_top.ui')
        loadUi(ui_file, self, {'TopicWidget': TopicWidget})

        # Monitor node
        self._node_qitems = {}
        self._init_monitor_nodes(self._nodes_monitored)
        #TODO: connect sys msg for nodes.

        # topic to show
        # Delegate GUI functionality to rqt_topic.TopicWidget.
        self._widget_topic.set_selected_topics(self._selected_topics)
        self._widget_topic.set_topic_specifier(TopicWidget.SELECT_BY_MSGTYPE)
        self._widget_topic.start()
        # To connect signal in a widget to PluginContainerWidget.
        #TODO: In this way, Signal from only one instance is hooked.
        # Not a good design at all.
        self.sig_sysmsg = self._widget_topic.sig_sysmsg

        # Init monitoring parameters.
        self._param_qitems = {}
        self._init_monitor_parameters(_params_monitored)

    def _init_monitor_nodes(self, nodes_monitored):
        """
        @type params_monitored: str[]
        """
        self._node_datamodel = QStandardItemModel(0, 2)
        self._root_qitem = self._node_datamodel.invisibleRootItem()
        self._view_nodes.setModel(self._node_datamodel)

        self._node_monitor_thread = NodeMonitorThread(self, self.sig_node,
                                                      nodes_monitored)
        self.sig_node.connect(self._monitor_nodes)
        self._node_monitor_thread.start()

    def _init_monitor_parameters(self, params_monitored):
        """
        @type params_monitored: str[]
        """
        self._param_datamodel = QStandardItemModel(0, 2)
        self._root_qitem = self._param_datamodel.invisibleRootItem()
        self._view_reconf.setModel(self._param_datamodel)

        self._param_check_thread = ParamCheckThread(self, self.sig_param,
                                                    params_monitored)
        self.sig_param.connect(self._monitor_parameters)
        self._param_check_thread.start()

    def _monitor_nodes(self, is_node_running, node_name):
        """
        Slot

        @type is_node_running: bool
        @type node_name: str
        """
        #TODO: What this method does is exactly the same with
        # monitor_parameters. Unify them.

        rospy.logdebug('is_node_running={} par_name={}'.format(is_node_running,
                                                              node_name))
        node_name = str(node_name)
        node_qitem = None
        if not node_name in self._node_qitems:
            node_qitem = QStandardItem(node_name)
            self._node_qitems[node_name] = node_qitem
            self._node_datamodel.appendRow(node_qitem)
        else:  # qsitem with the node name already exists.
            node_qitem = self._node_qitems[str(node_name)]

        qindex = self._node_datamodel.indexFromItem(node_qitem)
        _str_node_running = 'Not running'
        if is_node_running:
            _str_node_running = 'Running'
        qitem_node_status = QStandardItem(_str_node_running)
        self._node_datamodel.setItem(qindex.row(), 1, qitem_node_status)

    def _monitor_parameters(self, has_param, param_name):
        """
        Slot

        @type has_param: bool
        @type param_name: str
        """
        rospy.logdebug('has_param={} par_name={}'.format(has_param, param_name))
        param_name = str(param_name)
        param_qitem = None
        if not param_name in self._param_qitems:
            param_qitem = QStandardItem(param_name)
            self._param_qitems[param_name] = param_qitem
            self._param_datamodel.appendRow(param_qitem)
        else:  # qsitem with the param name already exists.
            param_qitem = self._param_qitems[str(param_name)]

        qindex = self._param_datamodel.indexFromItem(param_qitem)
        _str_param_found = 'Not found on Parameter Server'
        if has_param:
            _str_param_found = 'Found on Parameter Server'
        qitem_param_status = QStandardItem(_str_param_found)
        self._param_datamodel.setItem(qindex.row(), 1, qitem_param_status)
        #.insertColumn([qitem_param_status])

    def save_settings(self, plugin_settings, instance_settings):
        # instance_settings.set_value('splitter', self._splitter.saveState())
        pass

    def restore_settings(self, plugin_settings, instance_settings):
#        if instance_settings.contains('splitter'):
#            self._splitter.restoreState(instance_settings.value('splitter'))
#        else:
#            self._splitter.setSizes([100, 100, 200])
        pass

    def shutdown(self):
        # TODO: impl
        pass
Esempio n. 49
0
 def __init__(self):
     """
     Initializes the ModelLogger.
     """
     self.__log_model = QStandardItemModel(0, 4, None)
     self.__log_model.setHorizontalHeaderLabels(["type", "date", "location", "message"])
Esempio n. 50
0
class QtRappManager(Plugin):
    _update_rapps_signal = Signal()

    def __init__(self, context):
        self._context = context
        super(QtRappManager, self).__init__(context)

        self._init_ui(context)
        self._init_events()
        self._init_variables()
        self.spin()

    def _init_ui(self, context):
        self._widget = QWidget()
        self.setObjectName('QtRappManger')

        rospack = rospkg.RosPack()
        ui_file = os.path.join(rospack.get_path('rocon_qt_app_manager'), 'ui',
                               'qt_rapp_manager.ui')
        self._widget.setObjectName('QtRappManger')
        loadUi(ui_file, self._widget, {})

        if context.serial_number() > 1:
            self._widget.setWindowTitle(self._widget.windowTitle() +
                                        (' (%d)' % context.serial_number()))
        context.add_widget(self._widget)

        # Set view mode
        self._widget.rapp_grid.setViewMode(QListView.IconMode)
        # self._widget.rapp_grid.setViewMode(QListView.ListMode)

    def _init_events(self):
        # combo box change event
        self._widget.namespace_cbox.currentIndexChanged.connect(
            self._change_namespace)

        # Rapp single click event
        self._widget.rapp_grid.clicked.connect(self._rapp_single_click)
        # Rapp double click event
        self._widget.rapp_grid.doubleClicked.connect(self._rapp_double_click)

    def _init_variables(self):
        self.initialised = False

        # init
        self._qt_rapp_manager_info = QtRappManagerInfo(self._refresh_rapps)
        self._update_rapps_signal.connect(self._update_rapp_list)

        self._rapp_view_model = QStandardItemModel()
        self._widget.rapp_grid.setModel(self._rapp_view_model)
        self._widget.rapp_grid.setWrapping(True)
        self._widget.rapp_grid.setIconSize(QSize(60, 60))
        self._widget.rapp_grid.setSpacing(10)

        self._selected_rapp = None

    def spin(self):
        self._get_appmanager_namespaces()

    def _cleanup_rapps(self):
        self._rapp_view_model.clear()

    def _get_appmanager_namespaces(self):
        namespaces = self._qt_rapp_manager_info._get_namespaces()
        for namespace in namespaces:
            ns = namespace[:namespace.find('list_rapps')]
            self._widget.namespace_cbox.addItem(ns)

    def _exit(self):
        pass

###################################################################
# Events
###################################################################

    def _change_namespace(self, event):
        self._qt_rapp_manager_info.select_rapp_manager(
            self._widget.namespace_cbox.currentText())

    def _refresh_rapps(self):
        """
        Updates from qt_app_manager_info.
        """
        self._update_rapps_signal.emit()

    def _update_rapp_list(self):
        """
        Rapp manager namespace event
        """
        self._cleanup_rapps()
        available_rapps = self._qt_rapp_manager_info.get_available_rapps()
        running_rapps = self._qt_rapp_manager_info.get_running_rapps()

        for r, v in available_rapps.items():
            if r in running_rapps.keys():
                item = QRappItem(v, running=True)
            else:
                item = QRappItem(v, running=False)
            self._rapp_view_model.appendRow(item)

    def _rapp_single_click(self, index):
        qrapp = self._rapp_view_model.item(index.row())
        rapp = qrapp.getRapp()
        self._create_rapp_dialog(rapp)

    def _create_rapp_dialog(self, rapp):
        is_running = self._qt_rapp_manager_info.is_running_rapp(rapp)
        self._selected_rapp = rapp
        self._dialog = QtRappDialog(self._widget, rapp,
                                    self._qt_rapp_manager_info.start_rapp,
                                    self._qt_rapp_manager_info.stop_rapp,
                                    is_running)
        self._dialog.show()

    def _rapp_double_click(self, item):
        running_rapps = self._qt_rapp_manager_info.get_running_rapps()
        if len(running_rapps) > 0:
            names = [r['display_name'] for r in running_rapps.values()]
            show_message(self._widget, "Error",
                         "Rapp %s are already running" % names)
        else:
            self._start_rapp()

    def _start_rapp(self):
        result = self._qt_rapp_manager_info.start_rapp(
            self._selected_rapp['name'], [],
            self._selected_rapp['public_parameters'])
        show_message(self._widget, str(result.started), result.message)
        self._selected_rapp = None
        return result

    def _stop_rapp(self):
        result = self._qt_rapp_manager_info.stop_rapp()
        show_message(self._widget, str(result.stopped), result.message)
        self._selected_rapp = None
        return result
Esempio n. 51
0
class ModelLogger:
    """
    Convenience class for logging data.
    """
    
    def __init__(self):
        """
        Initializes the ModelLogger.
        """
        self.__log_model = QStandardItemModel(0, 4, None)
        self.__log_model.setHorizontalHeaderLabels(["type", "date", "location", "message"])


    def log(self, type, date, location, message):
        """
        Adds a log entry to the log_model.

        :param type: the type of the log_entry
        :type type: str
        :param date: the time of the log_entry
        :type date: Time
        :param location: the location, were the fault/info/... occured
        :type location: str
        :param message: the message of the log_entry
        :type message: str
        """
        self.__log_model.insertRow(0)
        self.__log_model.setData(self.__log_model.index(0, 0), str(type))
        self.__log_model.setData(self.__log_model.index(0, 1), time.strftime("%d.%m-%H:%M:%S", time.localtime(int(str(date)) / 1000000000)))
        self.__log_model.setData(self.__log_model.index(0, 2), str(location))
        self.__log_model.setData(self.__log_model.index(0, 3), str(message))


    def get_representation(self):
        """
        Returns the log as a QStandartItemModel

        :returns: the log-model
        :rtype: QStandartItemModel
        """
        return self.__log_model
Esempio n. 52
0
class NodeSelectorWidget(QWidget):
    _COL_NAMES = ['Node']

    # public signal
    _sig_node_selected = Signal(str)

    def __init__(self):
        super(NodeSelectorWidget, self).__init__()
        self.stretch = None

        ui_file = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                               'ui/node_selector.ui')
        loadUi(ui_file, self)

        #  Setup treeview and models
        self._std_model = QStandardItemModel()
        self._node_selector_view.setModel(self._std_model)
        self._rootitem = self._std_model.invisibleRootItem()

        self._nodes_previous = None

        # Calling this method updates the list of the node.
        # Initially done only once.
        self._update_nodetree()

        # Setting slot for when user clickes on QTreeView.
        selectionModel = self._node_selector_view.selectionModel()
        selectionModel.selectionChanged.connect(self._selection_changed_slot)

        #TODO(Isaac): Needs auto-update function enabled, once another function
        #             that updates node tree with maintaining collapse/expansion
        #             state. http://goo.gl/GuwYp can be a help.

        #        self.timer = QTimer()
        #        self.timer.timeout.connect(self._refresh_nodes)
        #        self.timer.start(5000) #  5sec interval is fast enough.

        self._collapse_button.pressed.connect(
            self._node_selector_view.collapseAll)
        self._expand_button.pressed.connect(self._node_selector_view.expandAll)

    def _selection_changed_slot(self, selected, deselected):
        """
        Overriden from QItemSelectionModel.
        
        :type new_item_select: QItemSelection
        :type old_item_select: QItemSelection
        """

        index_current = self._node_selector_view.selectionModel().currentIndex(
        )
        rospy.logdebug(
            '_selection_changed_slot row=%d col=%d data=%s ' +
            'data.parent=%s child(0, 0)=%s', index_current.row(),
            index_current.column(), index_current.data(Qt.DisplayRole),
            index_current.parent().data(Qt.DisplayRole),
            index_current.child(0, 0).data(Qt.DisplayRole))

        if not index_current.child(0, 0).data(Qt.DisplayRole) == None:
            return  #  Meaning the tree has no nodes.

        #  get the text of the selected item
        node_name_selected = self.get_full_grn_recur(index_current, '')
        rospy.logdebug('_selection_changed_slot node_name_selected=%s',
                       node_name_selected)
        self._sig_node_selected.emit(node_name_selected)

    def get_full_grn_recur(self, model_index, str_grn):
        """
        
        Create full path format of GRN (Graph Resource Names, see  
        http://www.ros.org/wiki/Names). 
        
        An example: /wide_stereo/left/image_color/compressed
        
        Bulid GRN by recursively transcending parents & children of 
        QModelIndex instance.
        
        Upon its very 1st call, the argument is the index where user clicks on on
        the view object (here QTreeView is used but should work with other View).
        str_grn can be 0-length string.           
        
        :type model_index: QModelIndex
        :type str_grn: str
        :param str_grn: This could be an incomplete or a complete GRN format.         
        """
        #TODO(Isaac) Consider moving this to rqt_py_common.

        rospy.logdebug('get_full_grn_recur in str=%s', str_grn)
        if model_index.data(Qt.DisplayRole) == None:
            return str_grn
        str_grn = '/' + str(model_index.data(Qt.DisplayRole)) + str_grn
        rospy.logdebug('get_full_grn_recur out str=%s', str_grn)
        return self.get_full_grn_recur(model_index.parent(), str_grn)

    def _update_nodetree(self):
        """
        """

        #TODO(Isaac): 11/25/2012 dynamic_reconfigure only returns params that
        #             are associated with nodes. In order to handle independent
        #             params, different approach needs taken.
        try:
            nodes = dynamic_reconfigure.find_reconfigure_services()
        except rosservice.ROSServiceIOException as e:
            rospy.logerr("Reconfigure GUI cannot connect to master.")
            raise e  # TODO Make sure 'raise' returns/finalizes this func.

        if not nodes == self._nodes_previous:
            paramname_prev = ''
            paramitem_top_prev = None
            i_debug = 0
            for node_name_grn in nodes:
                p = ParameterItem(node_name_grn)
                p.set_param_name(node_name_grn)
                names = p.get_param_names()

                i_debug += 1
                rospy.logdebug('_update_nodetree i=%d names=%s', i_debug,
                               names)

                self._add_tree_node(p, self._rootitem, names)

    def _add_tree_node(self, param_item_full, stditem_parent,
                       child_names_left):
        """
        
        Evaluate current node and the previous node on the same depth.
        If the name of both nodes is the same, current node instance is ignored.
        If not, the current node gets added to the same parent node.
        At the end, this function gets called recursively going down 1 level.
        
        :type param_item_full: ParameterItem
        :type stditem_parent: QStandardItem.
        :type child_names_left: List of str
        :param child_names_left: List of strings that is sorted in hierarchical 
                                 order of params.
        """
        #TODO(Isaac): Consider moving to rqt_py_common.

        name_curr = child_names_left.pop(0)
        stditem_curr = ParameterItem(param_item_full.get_raw_param_name())

        # item at the bottom is your most recent node.
        row_index_parent = stditem_parent.rowCount() - 1

        # Obtain and instantiate prev node in the same depth.
        name_prev = ''
        stditem_prev = None
        if not stditem_parent.child(row_index_parent) == None:
            stditem_prev = stditem_parent.child(row_index_parent)
            name_prev = stditem_prev.text()

        stditem = None
        if name_prev != name_curr:
            stditem_curr.setText(name_curr)
            stditem_parent.appendRow(stditem_curr)
            stditem = stditem_curr
        else:
            stditem = stditem_prev

        rospy.logdebug(
            'add_tree_node 1 name_curr=%s ' +
            '\n\t\t\t\t\tname_prev=%s row_index_parent=%d', name_curr,
            name_prev, row_index_parent)

        if len(child_names_left) != 0:
            #TODO: View & Model are closely bound here. Ideally isolate this 2.
            #       Maybe we should split into 2 classs, 1 handles view,
            #       the other does model.
            self._add_tree_node(param_item_full, stditem, child_names_left)

    def _refresh_nodes(self):
        #TODO(Isaac) In the future, do NOT remove all nodes. Instead,
        #            remove only the ones that are gone. And add new ones too.

        model = self._rootitem
        if model.hasChildren():
            row_count = model.rowCount()
            model.removeRows(0, row_count)
            rospy.logdebug("ParamWidget _refresh_nodes row_count=%s",
                           row_count)
        self._update_nodetree()

    def close_node(self):
        rospy.logdebug(" in close_node")
Esempio n. 53
0
class TreeviewWidgetSelectProve(QWidget):

    def __init__(self):
        super(TreeviewWidgetSelectProve, self).__init__()

        rp = rospkg.RosPack()
        ui_file = os.path.join(rp.get_path('rqt_prove'), 'resource',
                               #'treeview_non_custom.ui')  # Works with pyqt.
                               'treeview_with_custom.ui')  # No good.
        #loadUi(ui_file, self)
        loadUi(ui_file, self, {'CustomQTreeview': CustomQTreeview})

        self._std_model = QStandardItemModel()
        self._rootitem = self._std_model.invisibleRootItem()

        item_r_1 = QStandardItem("r1")

        self._rootitem.appendRow(item_r_1)

        print('_rootitem index={}'.format(self._rootitem.index()))

        self.treeview.setModel(self._std_model)
        self.selectionModel = self.treeview.selectionModel()
        self.selectionModel.selectionChanged.connect(
                                                 self._selection_changed_slot)

        print('del/sel?\tde/sel index\tde/sel.row\tde/sel.dat\tparent\tinternal id')

        self.show()

    def _selection_changed_slot(self, selected, deselected):
        """
        Receives args from signal QItemSelectionModel.selectionChanged.

        :type selected: QItemSelection
        :type deselected: QItemSelection
        """
        self._test_sel_index(selected, deselected)

    def _test_sel_index(self, selected, deselected):
        src_model = self._std_model
        index_current = None
        index_deselected = None
        index_parent_sel = None
        index_parent_desel = None
        curr_qstd_item = None
        indexes = selected.indexes()
        del_or_sel = 'Sel'
        index_internalid = -1

        if len(indexes) > 0:
            index_internalid = selected.indexes()[0].internalId()

            # # Trying many approaches to get the right qindex
            # # Approach-1
            index_current = selected.indexes()[0]

            # # Approach-2

            # index_current_from_indexes = selected.indexes()[0]
            # index_current = src_model.index(index_current_from_indexes.row(),
                                            # 0, QModelIndex())
                                            # 0, index_current_from_indexes)
            # index_current = self.selectionModel.currentIndex()

            index_parent_sel = index_current.parent()
            curr_qstd_item = src_model.itemFromIndex(  # index_parent)
                                                 index_current)
        elif len(deselected.indexes()) > 0:
            index_internalid = deselected.indexes()[0].internalId()

            del_or_sel = 'Desel'
            index_deselected = self.selectionModel.currentIndex()
            index_parent_desel = index_deselected.parent()
            curr_qstd_item = src_model.itemFromIndex(index_deselected)

        tabular_format = '{}\t{}\t{}\t{}\t{}\t{}'
        if len(indexes) > 0:
            print(tabular_format.format(
                              del_or_sel,
                              index_current,
                              index_current.row(),
                              index_current.data(Qt.DisplayRole).toString(),
                                  #curr_qstd_item,
                                  #curr_qstd_item.data(Qt.DisplayRole),
                              index_parent_sel,
                                  #index_parent_sel.data(Qt.DisplayRole),
                              index_internalid))
        elif len(deselected.indexes()) > 0:
            print(tabular_format.format(
                              del_or_sel,
                              index_deselected,
                              index_deselected.row(),
                              index_deselected.data(Qt.DisplayRole).toString(),
                              #curr_qstd_item,
                              #    curr_qstd_item.data(),
                                  index_parent_desel,
                              #  index_parent_desel.data(Qt.DisplayRole),
                                  index_internalid))
            self.selectionModel.select(index_deselected,
                                       QItemSelectionModel.Deselect)
Esempio n. 54
0
class LaunchWidget(QDialog):
    '''#TODO: comment
    '''

    # To be connected to PluginContainerWidget
    sig_sysmsg = Signal(str)

    def __init__(self, parent):
        '''
        @type parent: LaunchMain
        '''
        super(LaunchWidget, self).__init__()
        self._parent = parent

        self._config = None

        #TODO: should be configurable from gui
        self._port_roscore = 11311

        self._run_id = None

        self._rospack = rospkg.RosPack()
        ui_file = os.path.join(self._rospack.get_path('rqt_launch'),
                               'resource', 'launch_widget.ui')
        loadUi(ui_file, self)

        # row=0 allows any number of rows to be added.
        self._datamodel = QStandardItemModel(0, 1)

        master_uri = rosenv.get_master_uri()
        rospy.loginfo('LaunchWidget master_uri={}'.format(master_uri))
        self._delegate = NodeDelegate(master_uri,
                                      self._rospack)
        self._treeview.setModel(self._datamodel)
        self._treeview.setItemDelegate(self._delegate)

        # NodeController used in controller class for launch operation.
        self._node_controllers = []

        self._pushbutton_start_all.clicked.connect(self._parent.start_all)
        self._pushbutton_stop_all.clicked.connect(self._parent.stop_all)
        # Bind package selection with .launch file selection.
        self._combobox_pkg.currentIndexChanged[str].connect(
                                                 self._refresh_launchfiles)
        # Bind a launch file selection with launch GUI generation.
        self._combobox_launchfile_name.currentIndexChanged[str].connect(
                                                 self._load_launchfile_slot)
        self._update_pkgs_contain_launchfiles()

        # Used for removing previous nodes
        self._num_nodes_previous = 0

    def _load_launchfile_slot(self, launchfile_name):
        # Not yet sure why, but everytime combobox.currentIndexChanged occurs,
        # this method gets called twice with launchfile_name=='' in 1st call.
        if launchfile_name == None or launchfile_name == '':
            return

        _config = None

        rospy.logdebug('_load_launchfile_slot launchfile_name={}'.format(
                                                           launchfile_name))

        try:
            _config = self._create_launchconfig(launchfile_name,
                                                self._port_roscore)
            #TODO: folder_name_launchfile should be able to specify arbitrarily
            # _create_launchconfig takes 3rd arg for it.

        except IndexError as e:
            msg = 'IndexError={} launchfile={}'.format(e.message,
                                                       launchfile_name)
            rospy.logerr(msg)
            self.sig_sysmsg.emit(msg)
            return
        except RLException as e:
            msg = 'RLException={} launchfile={}'.format(e.message,
                                                        launchfile_name)
            rospy.logerr(msg)
            self.sig_sysmsg.emit(msg)
            return

        self._create_widgets_for_launchfile(_config)

    def _create_launchconfig(self, launchfile_name, port_roscore=11311,
                             folder_name_launchfile='launch'):
        '''
        @rtype: ROSLaunchConfig
        @raises RLException: raised by roslaunch.config.load_config_default.
        '''

        pkg_name = self._combobox_pkg.currentText()

        try:
            launchfile = os.path.join(self._rospack.get_path(pkg_name),
                                      folder_name_launchfile, launchfile_name)
        except IndexError as e:
            raise RLException('IndexError: {}'.format(e.message))

        try:
            launch_config = roslaunch.config.load_config_default([launchfile],
                                                                 port_roscore)
        except rospkg.common.ResourceNotFound as e:
            raise RLException('ResourceNotFound: {}'.format(e.message))
        except RLException as e:
            raise e

        return launch_config

    def _create_widgets_for_launchfile(self, config):
        self._config = config

        # Delete old nodes' GUIs.
        self._node_controllers = []

        # These lines seem to remove indexWidgets previously set on treeview.
        # Per suggestion in API doc, we are not using reset(). Instead,
        # using 2 methods below without any operation in between, which
        # I suspect might be inproper.
        # http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#reset
        self._datamodel.beginResetModel()
        self._datamodel.endResetModel()

        # Need to store the num of nodes outside of the loop -- this will
        # be used for removing excessive previous node rows.
        order_xmlelement = 0
        # Loop per xml element
        for order_xmlelement, node in enumerate(self._config.nodes):
            proxy = NodeProxy(self._run_id, self._config.master.uri, node)

            # TODO: consider using QIcon.fromTheme()
            status_label = StatusIndicator()

            qindex_nodewidget = self._datamodel.index(order_xmlelement,
                                                       0, QModelIndex())
            node_widget = self._delegate.create_node_widget(qindex_nodewidget,
                                                            proxy.config,
                                                            status_label)

            #TODO: Ideally find a way so that we don't need this block.
            #BEGIN If these lines are missing, widget won't be shown either.
            std_item = QStandardItem(
                                     #node_widget.get_node_name()
                                     )
            self._datamodel.setItem(order_xmlelement, 0, std_item)
            #END If these lines are missing, widget won't be shown either.

            self._treeview.setIndexWidget(qindex_nodewidget, node_widget)

            node_controller = NodeController(proxy, node_widget)
            self._node_controllers.append(node_controller)

            node_widget.connect_start_stop_button( \
                                       node_controller.start_stop_slot)
            rospy.logdebug('loop #%d proxy.config.namespace=%s ' +
                          'proxy.config.name=%s',
                          order_xmlelement, proxy.config.namespace,
                          proxy.config.name)

        self._num_nodes_previous = order_xmlelement

        self._parent.set_node_controllers(self._node_controllers)

    def _update_pkgs_contain_launchfiles(self):
        '''
        Inspired by rqt_msg.MessageWidget._update_pkgs_contain_launchfiles
        '''
        packages = sorted([pkg_tuple[0]
                           for pkg_tuple
                           in RqtRoscommUtil.iterate_packages('launch')])
        self._package_list = packages
        rospy.logdebug('pkgs={}'.format(self._package_list))
        self._combobox_pkg.clear()
        self._combobox_pkg.addItems(self._package_list)
        self._combobox_pkg.setCurrentIndex(0)

    def _refresh_launchfiles(self, package=None):
        '''
        Inspired by rqt_msg.MessageWidget._refresh_msgs
        '''
        if package is None or len(package) == 0:
            return
        self._launchfile_instances = []  # Launch[]
        #TODO: RqtRoscommUtil.list_files's 2nd arg 'subdir' should NOT be
        # hardcoded later.
        _launch_instance_list = RqtRoscommUtil.list_files(package,
                                                         'launch')

        rospy.logdebug('_refresh_launches package={} instance_list={}'.format(
                                                       package,
                                                       _launch_instance_list))

        self._launchfile_instances = [x.split('/')[1]
                                      for x in _launch_instance_list]

        self._combobox_launchfile_name.clear()
        self._combobox_launchfile_name.addItems(self._launchfile_instances)

    def save_settings(self, plugin_settings, instance_settings):
        # instance_settings.set_value('splitter', self._splitter.saveState())
        pass

    def restore_settings(self, plugin_settings, instance_settings):
#        if instance_settings.contains('splitter'):
#            self._splitter.restoreState(instance_settings.value('splitter'))
#        else:
#            self._splitter.setSizes([100, 100, 200])
        pass
Esempio n. 55
0
class MoveitWidget(QWidget):
    """#TODO: comment
    """
    # To be connected to PluginContainerWidget
    sig_sysmsg = None
    sig_param = Signal(bool, str)  # param name emitted
    sig_node = Signal(bool, str)  # param name emitted

    _SPLITTER_H = 'splitter_horizontal'

    def __init__(self, parent, plugin_context):
        """
        @type parent: MoveitMain
        """

        self._nodes_monitored = ['/move_group']
        self._selected_topics = [('/pointcloud', 'sensor_msgs/PointCloud'),
                                 ('/pointcloud2', 'sensor_msgs/PointCloud2'),
                                 ('/image', 'sensor_msgs/Image'),
                                 ('/camera_info', 'sensor_msgs/CameraInfo')]
        self._params_monitored = ['/robot_description',
                                  '/robot_description_semantic']

        super(MoveitWidget, self).__init__()
        self._parent = parent
        self._plugin_context = plugin_context
        self._refresh_rate = 5  # With default value

        self._rospack = rospkg.RosPack()
        ui_file = os.path.join(self._rospack.get_path('rqt_moveit'),
                               'resource', 'moveit_top.ui')
        loadUi(ui_file, self, {'TopicWidget': TopicWidget})

        # Custom widget classes don't show in QSplitter when they instantiated
        # in .ui file and not explicitly added to QSplitter like this. Thus
        # this is a workaround.
        self._splitter.addWidget(self._widget_topic)

        self._spinbox_refreshrate.valueChanged.connect(
                                                      self._update_refreshrate)
        # Show default ref rate on QSpinbox
        self._spinbox_refreshrate.setValue(self._refresh_rate)

        # Monitor node
        self._is_checking_nodes = True
        self._node_qitems = {}
        self._node_monitor_thread = self._init_monitor_nodes(
                                                         self._nodes_monitored)
        self._node_monitor_thread.start()
        #TODO: connect sys msg for nodes.

        # topic to show
        # Delegate GUI functionality to rqt_topic.TopicWidget.
        self._widget_topic.set_selected_topics(self._selected_topics)
        self._widget_topic.set_topic_specifier(TopicWidget.SELECT_BY_MSGTYPE)
        self._widget_topic.start()
        # To connect signal in a widget to PluginContainerWidget.
        #TODO: In this way, Signal from only one instance is hooked.
        # Not a good design at all.
        self.sig_sysmsg = self._widget_topic.sig_sysmsg

        # Init monitoring parameters.
        self._is_checking_params = True
        self._param_qitems = {}
        _col_names_paramtable = ['Param name', 'Found on Parameter Server?']
        self._param_check_thread = self._init_monitor_parameters(
                                                      self._params_monitored,
                                                      _col_names_paramtable)
        self._param_check_thread.start()

    def _init_monitor_nodes(self, nodes_monitored):
        """
        @type params_monitored: str[]
        @rtype: Thread
        """
        self._node_datamodel = QStandardItemModel(0, 2)
        self._root_qitem = self._node_datamodel.invisibleRootItem()
        self._view_nodes.setModel(self._node_datamodel)

        node_monitor_thread = Thread(target=self._check_nodes_alive,
                                           args=(self.sig_node,
                                                 self._nodes_monitored))
#        self._node_monitor_thread = NodeMonitorThread(self, self.sig_node,
#                                                      nodes_monitored)
        self.sig_node.connect(self._update_output_nodes)
        return node_monitor_thread

    def _check_nodes_alive(self, signal, nodes_monitored):
        """
        Working as a callback of Thread class, this method keeps looping to
        watch if the nodes whose names are passed exist and emits signal per
        each node.

        Notice that what MoveitWidget._check_nodes_alive &
        MoveitWidget._check_params_alive do is very similar, but since both of
        them are supposed to be passed to Thread class, there might not be
        a way to generalize these 2.

        @param signal: Signal(bool, str)
        @type nodes_monitored: str[]
        """
        while self._is_checking_nodes:
            rosnode_dynamically_loaded = __import__('rosnode')
            #from rosnode import rosnode_ping
            for nodename in nodes_monitored:
                #TODO: rosnode_ping prints when the node is not found.
                # Currently I have no idea how to capture that from here.
                try:
                    #is_node_running = rosnode_ping(nodename, 1)
                    is_node_running = rosnode_dynamically_loaded.rosnode_ping(
                                                                 nodename, 1)
                except rosnode_dynamically_loaded.ROSNodeIOException as e:
                    #TODO: Needs to be indicated on GUI
                    #      (eg. PluginContainerWidget)
                    rospy.logerr(e.message)
                    is_node_running = False

                signal.emit(is_node_running, nodename)
                rospy.logdebug('_update_output_nodes')
            del rosnode_dynamically_loaded
            time.sleep(self._refresh_rate)

    def _init_monitor_parameters(self, params_monitored,
                                 _col_names_paramtable=None):
        """
        @type params_monitored: str[]
        """
        self._params_monitored = params_monitored

        self._param_datamodel = QStandardItemModel(0, 2)
        self._root_qitem = self._param_datamodel.invisibleRootItem()
        self._view_params.setModel(self._param_datamodel)

        # Names of header on the QTableView.
        if not _col_names_paramtable:
            _col_names_paramtable = ['Param name',
                                     'Found on Parameter Server?']
        self._param_datamodel.setHorizontalHeaderLabels(_col_names_paramtable)

        self.sig_param.connect(self._update_output_parameters)

        param_check_thread = Thread(target=self._check_params_alive,
                                    args=(self.sig_param,
                                          self._params_monitored))
        return param_check_thread

    def _update_output_nodes(self, is_node_running, node_name):
        """
        Slot for signals that tell nodes existence.

        @type is_node_running: bool
        @type node_name: str
        """
        #TODO: What this method does is exactly the same with
        # monitor_parameters. Unify them.

        rospy.logdebug('is_node_running={} par_name={}'.format(is_node_running,
                                                              node_name))
        node_name = str(node_name)
        node_qitem = None
        if not node_name in self._node_qitems:
            node_qitem = QStandardItem(node_name)
            self._node_qitems[node_name] = node_qitem
            self._node_datamodel.appendRow(node_qitem)
        else:  # qsitem with the node name already exists.
            node_qitem = self._node_qitems[str(node_name)]

        qindex = self._node_datamodel.indexFromItem(node_qitem)
        _str_node_running = 'Not running'
        if is_node_running:
            _str_node_running = 'Running'
        qitem_node_status = QStandardItem(_str_node_running)
        self._node_datamodel.setItem(qindex.row(), 1, qitem_node_status)

    def _check_params_alive(self, signal, params_monitored):
        """
        Working as a callback of Thread class, this method keeps looping to
        watch if the params whose names are passed exist and emits signal per
        each node.

        Notice that what MoveitWidget._check_nodes_alive &
        MoveitWidget._check_params_alive do is very similar, but since both of
        them are supposed to be passed to Thread class, there might not be
        a way to generalize these 2.

        @type signal: Signal(bool, str)
        @param_name signal: emitting a name of the parameter that's found.
        @type params_monitored: str[]
        """

        while self._is_checking_params:
            # self._is_checking_params only turns to false when the plugin
            # shuts down.

            has_param = False

            for param_name in params_monitored:
                is_rosmaster_running = RqtRoscommUtil.is_roscore_running()

                try:
                    if is_rosmaster_running:
                        # Only if rosmaster is running, check if the parameter
                        # exists or not.
                        has_param = rospy.has_param(param_name)
                except rospy.exceptions.ROSException as e:
                    self.sig_sysmsg.emit(
                         'Exception upon rospy.has_param {}'.format(e.message))
                signal.emit(has_param, param_name)
                rospy.loginfo('has_param {}, check_param_alive: {}'.format(
                                                      has_param, param_name))
            time.sleep(self._refresh_rate)

    def _update_output_parameters(self, has_param, param_name):
        """
        Slot

        @type has_param: bool
        @type param_name: str
        """
        rospy.logdebug('has_param={} par_name={}'.format(has_param,
                                                         param_name))
        param_name = str(param_name)
        param_qitem = None
        if not param_name in self._param_qitems:
            param_qitem = QStandardItem(param_name)
            self._param_qitems[param_name] = param_qitem
            self._param_datamodel.appendRow(param_qitem)
        else:  # qsitem with the param name already exists.
            param_qitem = self._param_qitems[str(param_name)]

        qindex = self._param_datamodel.indexFromItem(param_qitem)
        _str_param_found = 'No'
        if has_param:
            _str_param_found = 'Yes'
        qitem_param_status = QStandardItem(_str_param_found)
        self._param_datamodel.setItem(qindex.row(), 1, qitem_param_status)
        self._view_params.resizeColumnsToContents()

    def _update_refreshrate(self, refresh_rate):
        """
        Slot

        @type refresh_rate: int
        """
        self._refresh_rate = refresh_rate

    def save_settings(self, plugin_settings, instance_settings):
        instance_settings.set_value(self._SPLITTER_H,
                                    self._splitter.saveState())

    def restore_settings(self, plugin_settings, instance_settings):
        if instance_settings.contains(self._SPLITTER_H):
            self._splitter.restoreState(instance_settings.value(
                                                             self._SPLITTER_H))
        else:
            self._splitter.setSizes([100, 100, 200])
        pass

    def shutdown(self):
        """
        Overridden.

        Close threads.

        @raise RuntimeError:
        """
        try:
            #self._node_monitor_thread.join()  # No effect
            self._is_checking_nodes = False
            self._node_monitor_thread = None
            #self._param_check_thread.join()

            self._is_checking_params = False
            self._param_check_thread = None
        except RuntimeError as e:
            rospy.logerr(e)
            raise e
 def __init__(self, parent=None):
     # FIXME: why is this not working? should be the same as the following line...
     #super(MessageTreeModel, self).__init__(parent)
     QStandardItemModel.__init__(self, parent)
Esempio n. 57
0
 def _empty_item_model():
     return QStandardItemModel()