Ejemplo n.º 1
0
    def __init__(self):
        super(TopicSelection, self).__init__()
        master = rosgraph.Master('rqt_bag_recorder')
        self.setWindowTitle("Select the topics you want to record")
        self.resize(500, 700)

        self.topic_list = []
        self.selected_topics = []
        self.items_list = []

        self.area = QScrollArea(self)
        self.main_widget = QWidget(self.area)
        self.ok_button = QPushButton("Record", self)
        self.ok_button.clicked.connect(self.onButtonClicked)
        self.ok_button.setEnabled(False)

        self.main_vlayout = QVBoxLayout(self)
        self.main_vlayout.addWidget(self.area)
        self.main_vlayout.addWidget(self.ok_button)
        self.setLayout(self.main_vlayout)

        self.selection_vlayout = QVBoxLayout(self)
        self.item_all = QCheckBox("All", self)
        self.item_all.stateChanged.connect(self.updateList)
        self.selection_vlayout.addWidget(self.item_all)
        topic_data_list = master.getPublishedTopics('')
        topic_data_list.sort()
        for topic, datatype in topic_data_list:
            self.addCheckBox(topic)

        self.main_widget.setLayout(self.selection_vlayout)

        self.area.setWidget(self.main_widget)
        self.show()
 def __init__(self, parent=None):
     super(PlotWidget, self).__init__(parent)
     # create widgets
     self.canvas = PlotCanvas()
     vbox = QVBoxLayout()
     vbox.addWidget(self.canvas)
     self.setLayout(vbox)
Ejemplo n.º 3
0
    def __init__(self, parent=None):
        super(MatDataPlot, self).__init__(parent)
        self._canvas = MatDataPlot.Canvas()
        self._toolbar = NavigationToolbar(self._canvas, self._canvas)
        vbox = QVBoxLayout()
        vbox.addWidget(self._toolbar)
        vbox.addWidget(self._canvas)
        self.setLayout(vbox)

        self._curves = {}
        self._current_vline = None
        self._canvas.mpl_connect('button_release_event', self._limits_changed)
    def __init__(self, parent=None):
        super(PyQtGraphDataPlot, self).__init__(parent)
        self._plot_widget = PlotWidget()
        self._plot_widget.getPlotItem().addLegend()
        self._plot_widget.setBackground((255, 255, 255))
        self._plot_widget.setXRange(0, 10, padding=0)
        vbox = QVBoxLayout()
        vbox.addWidget(self._plot_widget)
        self.setLayout(vbox)
        self._plot_widget.getPlotItem().sigRangeChanged.connect(self.limits_changed)

        self._curves = {}
        self._current_vline = None
Ejemplo n.º 5
0
    def __init__(self, map_topic='/map',
                 paths=['/move_base/NavFn/plan', '/move_base/TrajectoryPlannerROS/local_plan'],
                 polygons=['/move_base/local_costmap/robot_footprint']):
        super(NavViewWidget, self).__init__()
        self._layout = QVBoxLayout()
        self._button_layout = QHBoxLayout()

        self.setAcceptDrops(True)
        self.setWindowTitle('Navigation Viewer')

        self.paths = paths
        self.polygons = polygons
        self.map = map_topic
        self._tf = tf.TransformListener()

        self._nav_view = NavView(map_topic, paths, polygons, tf = self._tf, parent = self)

        self._set_pose = QPushButton('Set Pose')
        self._set_pose.clicked.connect(self._nav_view.pose_mode)
        self._set_goal = QPushButton('Set Goal')
        self._set_goal.clicked.connect(self._nav_view.goal_mode)

        self._button_layout.addWidget(self._set_pose)
        self._button_layout.addWidget(self._set_goal)

        self._layout.addLayout(self._button_layout)

        self._layout.addWidget(self._nav_view)

        self.setLayout(self._layout)
Ejemplo n.º 6
0
    def __init__(self, parent, name, timeline):
        """
        :param name: Name of inspecting diagnostic status
        :param timeline: Timeline object from which a status is fetched
        """
        #TODO(Isaac) UI construction that currently is done in this method,
        #            needs to be done in .ui file.
        super(InspectorWindow, self).__init__(parent=parent)
        self.setWindowTitle(name)
        self._name = name

        self.layout_vertical = QVBoxLayout(self)

        self.disp = StatusSnapshot(parent=self)

        self.layout_vertical.addWidget(self.disp, 1)

        self._message_updated_processing = False
        self._queue_updated_processing = False

        self.timeline = timeline
        self.timeline.message_updated.connect(self.message_updated,
                                              Qt.DirectConnection)
        self.timeline.queue_updated.connect(self.queue_updated,
                                            Qt.DirectConnection)
        self._message_updated.connect(self._signal_message_updated,
                                      Qt.QueuedConnection)
        self._queue_updated.connect(self._signal_queue_updated,
                                    Qt.QueuedConnection)

        self.timeline_pane = TimelinePane(self, self.timeline.paused)
        self.timeline_pane.pause_changed.connect(self.timeline.set_paused)
        self.timeline_pane.position_changed.connect(self.timeline.set_position)
        self.timeline.pause_changed.connect(self.timeline_pane.set_paused)
        self.timeline.position_changed.connect(self.timeline_pane.set_position)
        self.layout_vertical.addWidget(self.timeline_pane, 0)

        self.snapshot = QPushButton("Snapshot")
        self.snapshot.clicked.connect(self._take_snapshot)
        self.layout_vertical.addWidget(self.snapshot)

        self.snaps = []

        self.setLayout(self.layout_vertical)
        # TODO better to be configurable where to appear.
        self.resize(400, 600)
Ejemplo n.º 7
0
    def __init__(self):
        super(ParameditWidget, self).__init__()

        _, package_path = get_resource('packages', 'rqt_reconfigure')
        ui_file = os.path.join(package_path, 'share', 'rqt_reconfigure',
                               'resource', 'paramedit_pane.ui')
        loadUi(ui_file, self, {'ParameditWidget': ParameditWidget})

        self._param_client_widgets = OrderedDict()

        # Adding the list of Items
        self._vlayout = QVBoxLayout(self.scrollarea_holder_widget)

        # causes error
        # self._set_index_widgets(self.listview, paramitems_dict)

        self.destroyed.connect(self.close)
Ejemplo n.º 8
0
    def __init__(self, node):
        super(ControlWidget, self).__init__()
        layout = QVBoxLayout(self)
        self.static_canvas = FigureCanvas(Figure(figsize=(5, 3)))
        layout.addWidget(self.static_canvas)
        self.control_truth = []
        self.control_estimate = []
        self.control_estimate_argmax = []
        self.control_prediction = []
        self.control_prediction_argmax = []
        self.estimate_types = []
        self.ax = self.static_canvas.figure.subplots()

        self.ax.set_xlim(0, 50)
        self.ax.set_ylim(-0.1, 1.1)
        self.ax.set_title('Control History')
        self.ax.legend()
        self.ax.set_yticks([0, 1])
        self.ax.set_yticklabels(['2g', '3g'])
        self.ax.set_xlabel('Time')
        self.ax.set_ylabel('Control')
        self.ax.grid()
        # t = np.linspace(0, 10, 501)
        # self.ax.plot(t, np.sin(t), ".")

        # # Create QWidget
        # # ui_file = os.path.join(rospkg.RosPack().get_path('rqt_dot'), 'resource', 'rqt_dot.ui')
        # _, package_path = get_resource('packages', 'rqt_dot')
        # ui_file = os.path.join(package_path, 'share', 'rqt_dot', 'resource', 'rqt_dot.ui')
        # loadUi(ui_file, self, {'DotWidget':DotWidget})
        # self.setObjectName('ROSDot')
        #
        # self.refreshButton.clicked[bool].connect(self._handle_refresh_clicked)
        # self.saveButton.clicked[bool].connect(self._handle_save_button_clicked)
        #
        # # flag used to zoom out to fit graph the first time it's received
        # self.first_time_graph_received = True
        # # to store the graph msg received in callback, later on is used to save the graph if needed
        # self.graph = None
        self.topic_name = 'graph_string'
        self._node = node
        self._node.create_subscription(ControlPList, 'control_estimate',
                                       self.ReceivedEstimateCallback, 10)
        self._node.create_subscription(ControlA, 'control_data',
                                       self.ReceivedTruthCallback, 10)
Ejemplo n.º 9
0
 def beginGui(self,obj):
     self.parent = QScrollArea()
     self.frame = QFrame(self.parent)
     if obj.layout == "vertical":
         self.tl = QVBoxLayout()
     else:
         self.tl = QHBoxLayout()
         
     self.__increase_nesting_level(self.frame,self.tl)
Ejemplo n.º 10
0
    def __init__(self, parent=None):
        super(RawDataSelector, self).__init__()
        self.parent = parent
        self.setTitle('Select bag file')

        # Init the components
        self.bag1RadioBtn = QRadioButton('ground truth')
        self.bag2RadioBtn = QRadioButton('camera')

        # connect the signals to the slots
        self.bag1RadioBtn.clicked.connect(self.btn1Clicked)
        self.bag2RadioBtn.clicked.connect(self.btn2Clicked)

        # layout
        layout = QVBoxLayout()
        layout.addWidget(self.bag1RadioBtn)
        layout.addWidget(self.bag2RadioBtn)
        self.setLayout(layout)
Ejemplo n.º 11
0
    def __init__(self):
        super(TopicSelection, self).__init__()
        master = rosgraph.Master('rqt_bag_recorder')
        self.setWindowTitle("Select the topics you want to record")
        self.resize(500, 700)

        self.topic_list = []
        self.selected_topics = []
        self.items_list = []

        self.area = QScrollArea(self)
        self.main_widget = QWidget(self.area)
        self.ok_button = QPushButton("Record", self)
        self.ok_button.clicked.connect(self.onButtonClicked)
        self.ok_button.setEnabled(False)

        self.from_nodes_button = QPushButton("From Nodes", self)
        self.from_nodes_button.clicked.connect(self.onFromNodesButtonClicked)

        self.main_vlayout = QVBoxLayout(self)
        self.main_vlayout.addWidget(self.area)
        self.main_vlayout.addWidget(self.ok_button)
        self.main_vlayout.addWidget(self.from_nodes_button)
        self.setLayout(self.main_vlayout)

        self.selection_vlayout = QVBoxLayout(self)
        self.item_all = QCheckBox("All", self)
        self.item_monitor = QCheckBox("Monitor", self)
        self.item_monAge = QCheckBox("Monitor + Agents", self)
        self.item_all.stateChanged.connect(self.updateList)
        self.item_monitor.stateChanged.connect(lambda x: self.updateList(x, "Monitor"))
        self.item_monAge.stateChanged.connect(lambda x: self.updateList(x, "Monitor+"))
        self.selection_vlayout.addWidget(self.item_all)
        self.selection_vlayout.addWidget(self.item_monitor)
        self.selection_vlayout.addWidget(self.item_monAge)
        topic_data_list = master.getPublishedTopics('')
        topic_data_list.sort()
        for topic, datatype in topic_data_list:
            self.addCheckBox(topic)

        self.main_widget.setLayout(self.selection_vlayout)

        self.area.setWidget(self.main_widget)
        self.show()
Ejemplo n.º 12
0
class OperationSelectorWidget(QGroupBox):
    
    selectionChanged = QtCore.Signal(str)
    
    operations = [
                  'true positive', 
                  'mismatch',
                  'false positive', 
                  'false negative', 
                  'precision',
                  'recall'
                  ]
    
    
    def __init__(self, parent=None):
        super(OperationSelectorWidget, self).__init__()
        self.parent = parent
        self.setTitle('Select Value')
        
        self.layout = QVBoxLayout()
        self.initRadioButtons()
        self._currentSelected = ''
        
        self.setLayout(self.layout)
        
        
    def initRadioButtons(self):
        for operation in self.operations:
            btn = QRadioButton(operation)
            btn.clicked.connect(lambda state, x=operation: self.switchOperation(x))  
            self.layout.addWidget(btn)
            
            
    def switchOperation(self, operation):
        self._currentSelected = operation
        self.selectionChanged.emit(operation)
        
        
    def getOperation(self):
        return self._currentSelected
        
            
        
Ejemplo n.º 13
0
    def __init__(self, status, close_callback):
        """
        :type status: DiagnosticStatus
        :param close_callback: When the instance of this class
                               (InspectorWindow) terminates, this callback gets
                               called.
        """
        #TODO(Isaac) UI construction that currently is done in this method,
        #            needs to be done in .ui file.

        super(InspectorWindow, self).__init__()
        self.status = status
        self._close_callback = close_callback
        self.setWindowTitle(status.name)
        self.paused = False

        self.layout_vertical = QVBoxLayout(self)

        self.disp = QTextEdit(self)
        self.snapshot = QPushButton("StatusSnapshot")

        self.timeline_pane = TimelinePane(self)
        self.timeline_pane.set_timeline_data(Util.SECONDS_TIMELINE,
                                             self.get_color_for_value,
                                             self.on_pause)

        self.layout_vertical.addWidget(self.disp, 1)
        self.layout_vertical.addWidget(self.timeline_pane, 0)
        self.layout_vertical.addWidget(self.snapshot)

        self.snaps = []
        self.snapshot.clicked.connect(self._take_snapshot)

        self._sig_write.connect(self._write_key_val)
        self._sig_newline.connect(lambda: self.disp.insertPlainText('\n'))
        self._sig_clear.connect(lambda: self.disp.clear())
        self._sig_close_window.connect(self._close_callback)

        self.setLayout(self.layout_vertical)
        # TODO better to be configurable where to appear.
        self.setGeometry(0, 0, 400, 600)
        self.show()
        self.update_status_display(status)
Ejemplo n.º 14
0
    def __init__(self, plugin=None):
        """
        """
        super(SystemWidget, self).__init__()

        rp = rospkg.RosPack()
        ui_file = os.path.join(rp.get_path('rqt_agent'), 'resource',
                               'SystemWidget.ui')
        loadUi(ui_file, self)

        self._plugin = plugin

        self._subsystems = {}

        self.all_subsystems = {}
        self._widgets = {}
        self.prev_subsystems = []
        self.levels_layouts = []

        self.structure_root = None
        self.structure_graph = None

        self.structure_changed = False

        self.scrollArea = QScrollArea()
        self.scrollArea.setWidgetResizable(True)
        self.horizontalLayout.addWidget(self.scrollArea)
        self.mainWidget = QWidget()
        self.scrollArea.setWidget(self.mainWidget)
        self.verticalLayout = QVBoxLayout()
        self.mainWidget.setLayout(self.verticalLayout)

        #        self._tree_items = {}
        #        self._column_index = {}
        #        for column_name in self._column_names:
        #            self._column_index[column_name] = len(self._column_index)

        # self.refresh_topics()

        # init and start update timer
        self._timer_refresh_topics = QTimer(self)
        self._timer_refresh_topics.timeout.connect(self.refresh_topics)
Ejemplo n.º 15
0
 def beginGroup(self,obj):
     parent,layout = self.__get_immediate_parent()
     panel = QGroupBox(obj.name,parent)
     if obj.layout == "grid":
         l = QGridLayout()
     elif obj.layout == "vertical":
         l = QVBoxLayout()
     else:
         l = QHBoxLayout()
     
     self.__increase_nesting_level(panel, l)
    def setup_group_frame(self, group):
        layout = QVBoxLayout()

        # grid for buttons for named targets
        grid = QGridLayout()
        grid.setSpacing(1)

        self.button_group = QButtonGroup(self)

        row = 0
        column = 0
        named_targets = self.get_named_targets(group)
        for target in named_targets:
            button = QPushButton(target)
            self.button_group.addButton(button)
            grid.addWidget(button, row, column)
            column += 1
            if column >= self.MAX_COLUMNS:
                row += 1
                column = 0

        self.button_group.buttonClicked.connect(self._handle_button_clicked)

        # grid for show joint value and move arm buttons/text field
        joint_values_grid = QGridLayout()
        joint_values_grid.setSpacing(1)

        button_show_joint_values = QPushButton('Current Joint Values')
        button_show_joint_values.clicked[bool].connect(
            self._handle_show_joint_values_clicked)

        line_edit = QLineEdit()
        self.text_joint_values.append(line_edit)

        button_move_to = QPushButton('Move to')
        button_move_to.clicked[bool].connect(self._handle_move_to_clicked)

        joint_values_grid.addWidget(button_show_joint_values, 0, 1)
        joint_values_grid.addWidget(line_edit, 0, 2)
        joint_values_grid.addWidget(button_move_to, 0, 3)

        layout.addLayout(grid)
        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)
        layout.addWidget(line)
        layout.addLayout(joint_values_grid)

        frame = QFrame()
        frame.setLayout(layout)
        return frame
Ejemplo n.º 17
0
    def add_item_to_conversation_view(self, msg, type=0):
        label_msg = QLabel(msg)
        label_msg.setWordWrap(True)
        label_msg.setStyleSheet('font-size:10pt;')

        inner_text_layout = QHBoxLayout()
        horizonalSpacer1 = QSpacerItem(0, 0, QSizePolicy.MinimumExpanding,
                                       QSizePolicy.MinimumExpanding)
        if type == 0:
            inner_text_layout.addWidget(label_msg)
            inner_text_layout.addItem(horizonalSpacer1)
        elif type == 1:
            inner_text_layout.addItem(horizonalSpacer1)
            inner_text_layout.addWidget(label_msg)

        inner_layout = QVBoxLayout()
        time_msg = QLabel(str(time.asctime(time.localtime(time.time()))))
        time_msg.setStyleSheet('font-size:8pt;')

        inner_layout.addItem(inner_text_layout)
        inner_layout.addWidget(time_msg)
        inner_layout.setSizeConstraint(QLayout.SetFixedSize)

        outer_layout = QHBoxLayout()
        horizonalSpacer2 = QSpacerItem(0, 0, QSizePolicy.MinimumExpanding,
                                       QSizePolicy.MinimumExpanding)
        if type == 0:
            label_msg.setStyleSheet(
                'background: #e5e5ea; padding: 6px; border-radius: 8px;')
            time_msg.setAlignment(Qt.AlignLeft)
            outer_layout.addItem(inner_layout)
            outer_layout.addItem(horizonalSpacer2)
        elif type == 1:
            label_msg.setStyleSheet(
                'background: #1d86f4; padding: 6px; border-radius: 8px; color:#fff;'
            )
            time_msg.setAlignment(Qt.AlignRight)
            outer_layout.addItem(horizonalSpacer2)
            outer_layout.addItem(inner_layout)
        outer_layout.setSizeConstraint(QLayout.SetMinimumSize)

        widget = QWidget()
        widget.setLayout(outer_layout)
        widget.resize(widget.sizeHint())

        item = QListWidgetItem()
        item.setSizeHint(widget.sizeHint())

        self._widget.listWidget.addItem(item)
        self._widget.listWidget.setItemWidget(item, widget)
        self._widget.listWidget.scrollToBottom()
Ejemplo n.º 18
0
    def __init__(self, popup_name, timeline, viewer_type, topic):
        super(TopicPopupWidget, self).__init__()
        self.setObjectName(popup_name)
        self.setWindowTitle(popup_name)

        layout = QVBoxLayout()
        self.setLayout(layout)

        self._timeline = timeline
        self._viewer_type = viewer_type
        self._topic = topic
        self._viewer = None
Ejemplo n.º 19
0
    def __init__(self, parent=None, current_values=None):
        super(BlacklistDialog, self).__init__(parent)
        self.setWindowTitle("Blacklist")
        vbox = QVBoxLayout()
        self.setLayout(vbox)

        self._blacklist = Blacklist()
        if isinstance(current_values, list):
            for val in current_values:
                self._blacklist.append(val)
        vbox.addWidget(self._blacklist)

        controls_layout = QHBoxLayout()
        add_button = QPushButton(icon=QIcon.fromTheme('list-add'))
        rem_button = QPushButton(icon=QIcon.fromTheme('list-remove'))
        ok_button = QPushButton("Ok")
        cancel_button = QPushButton("Cancel")
        add_button.clicked.connect(self._add_item)
        rem_button.clicked.connect(self._remove_item)
        ok_button.clicked.connect(self.accept)
        cancel_button.clicked.connect(self.reject)

        controls_layout.addWidget(add_button)
        controls_layout.addWidget(rem_button)
        controls_layout.addStretch(0)
        controls_layout.addWidget(ok_button)
        controls_layout.addWidget(cancel_button)
        vbox.addLayout(controls_layout)
Ejemplo n.º 20
0
    def __init__(self):
        super(GroundStationWidget, self).__init__()

        self._principle_layout = QBoxLayout(0)  # main layout is horizontal (0)
        self._map_layout = QVBoxLayout()
        self._principle_layout.addLayout(self._map_layout, 4)
        self._control_layout = QVBoxLayout()
        self._principle_layout.addLayout(self._control_layout, 3)

        self.setAcceptDrops(False)  # Dragging and Dropping not permitted
        self.setWindowTitle('ROSplane Ground Station')

        #=============================
        self._mw = MapWindow()
        self._map_layout.addWidget(self._mw)
        self._tv = PlotWidget()
        self._data_plot = DataPlot(self._tv)
        self._data_plot.set_autoscale(x=False)
        self._data_plot.set_autoscale(y=DataPlot.SCALE_EXTEND
                                      | DataPlot.SCALE_VISIBLE)
        self._data_plot.set_xlim([0, 10.0])
        self._tv.switch_data_plot_widget(self._data_plot)

        self._control_layout.addWidget(
            self._tv,
            1)  # ratio of these numbers determines window proportions
        self._ah = ArtificialHorizon()
        self._control_layout.addWidget(self._ah, 1)
        #=============================

        print('fake init')
        self.setLayout(self._principle_layout)

        # Global timer for marble_map and artificial_horizon
        self.interval = 100  # in milliseconds, period of regular update
        self.timer = QTimer(self)
        self.timer.setInterval(self.interval)
        self.timer.timeout.connect(self._mw._marble_map.update)
        self.timer.timeout.connect(self._ah.update)
        self.timer.start()
Ejemplo n.º 21
0
    def __init__(self, context):
        super(PyConsole, self).__init__(context)
        self.setObjectName('PyConsole')

        self._context = context
        self._use_spyderlib = _has_spyderlib
        self._console_widget = None
        self._widget = QWidget()
        self._widget.setLayout(QVBoxLayout())
        self._widget.layout().setContentsMargins(0, 0, 0, 0)
        if context.serial_number() > 1:
            self._widget.setWindowTitle(self._widget.windowTitle() + (' (%d)' % context.serial_number()))
        self._context.add_widget(self._widget)
Ejemplo n.º 22
0
    def __init__(self, context):
        super(MoveitCommanderWidget, self).__init__()
        self.setObjectName('MoveitCommanderWidget')

        self.groups = self.get_groups()
        self.commanders = [
            moveit_commander.MoveGroupCommander(group) for group in self.groups
        ]

        # list of QLineEdit fields used to display joint values
        self.text_joint_values = []

        self.MAX_COLUMNS = 4

        self.tab_widget = QTabWidget()
        for g in self.groups:
            frame = self.setup_group_frame(g)
            self.tab_widget.addTab(frame, g)

        widget_layout = QVBoxLayout()
        widget_layout.addWidget(self.tab_widget)
        self.setLayout(widget_layout)
Ejemplo n.º 23
0
class GroundStationWidget(QWidget):
    def __init__(self):
        super(GroundStationWidget, self).__init__()

        self._principle_layout = QBoxLayout(0)  # main layout is horizontal (0)
        self._principle_layout = QSplitter(Qt.Horizontal)
        self._map_layout = QVBoxLayout()
        map_widget = QWidget()
        map_widget.setLayout(self._map_layout)
        self._principle_layout.addWidget(map_widget)
        self._control_layout = QVBoxLayout()
        control_widget = QWidget()
        control_widget.setLayout(self._control_layout)
        self._principle_layout.addWidget(control_widget)

        self.setAcceptDrops(False)  # Dragging and Dropping not permitted
        self.setWindowTitle('ROSplane Ground Station')

        #=============================
        self._mw = MapWindow()
        self._map_layout.addWidget(self._mw)
        self._tv = PlotWidget()
        self._data_plot = DataPlot(self._tv)
        self._data_plot.set_autoscale(x=False)
        self._data_plot.set_autoscale(y=DataPlot.SCALE_EXTEND
                                      | DataPlot.SCALE_VISIBLE)
        self._data_plot.set_xlim([0, 10.0])
        self._tv.switch_data_plot_widget(self._data_plot)

        self._control_layout.addWidget(
            self._tv,
            1)  # ratio of these numbers determines window proportions
        self._ah = ArtificialHorizon()
        self._control_layout.addWidget(self._ah, 1)
        #=============================

        print('fake init')
        total_layout = QBoxLayout(QBoxLayout.TopToBottom)
        self._principle_layout.setHandleWidth(8)
        total_layout.addWidget(self._principle_layout)
        self.setLayout(total_layout)

        # Global timer for marble_map and artificial_horizon
        self.interval = 100  # in milliseconds, period of regular update
        self.timer = QTimer(self)
        self.timer.setInterval(self.interval)
        self.timer.timeout.connect(self._mw._marble_map.update)
        self.timer.timeout.connect(self._ah.update)
        self.timer.start()

    def closeEvent(self, event):
        self.timer.stop()

    def save_settings(self, plugin_settings,
                      instance_settings):  # have a file to read and write from
        print('fake save')  # < prints to terminal

    def restore_settings(self, plugin_settings, instance_settings):
        print('fake restore')
Ejemplo n.º 24
0
 def __init__(self, parent=None):
     super(MatPlot2D, self).__init__(parent)
     self._canvas = MatPlot2D.Canvas()
     self._toolbar = NavigationToolbar(self._canvas, self._canvas)
     vbox = QVBoxLayout()
     vbox.addWidget(self._toolbar)
     vbox.addWidget(self._canvas)
     self.setLayout(vbox)
Ejemplo n.º 25
0
    def __init__(self,
                 map_topic='/map',
                 paths=[
                     '/move_base/NavFn/plan',
                     '/move_base/TrajectoryPlannerROS/local_plan'
                 ],
                 polygons=['/move_base/local_costmap/robot_footprint']):
        super(NavViewWidget, self).__init__()
        self._layout = QVBoxLayout()
        self._button_layout = QHBoxLayout()

        self.setAcceptDrops(True)
        self.setWindowTitle('Navigation Viewer')

        self.paths = paths
        self.polygons = polygons
        self.map = map_topic
        self._tf = tf.TransformListener()

        self._nav_view = NavView(map_topic,
                                 paths,
                                 polygons,
                                 tf=self._tf,
                                 parent=self)

        self._set_pose = QPushButton('Set Pose')
        self._set_pose.clicked.connect(self._nav_view.pose_mode)
        self._set_goal = QPushButton('Set Goal')
        self._set_goal.clicked.connect(self._nav_view.goal_mode)

        self._button_layout.addWidget(self._set_pose)
        self._button_layout.addWidget(self._set_goal)

        self._layout.addLayout(self._button_layout)

        self._layout.addWidget(self._nav_view)

        self.setLayout(self._layout)
Ejemplo n.º 26
0
    def __init__(self, context):
        super(LevelSelectorPlugin, self).__init__(context)
        # Give QObjects reasonable names
        self.setObjectName('LevelSelectorPlugin')

        # Create QWidget
        self._widget = QWidget()
        self._widget.setFont(QFont("Times", 15, QFont.Bold))
        self._button_layout = QVBoxLayout(self._widget)

        self.buttons = []
        self.text_label = QLabel("Waiting for MultiLevelMapData...", self._widget)
        self._button_layout.addWidget(self.text_label)

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

        self.button_signal.connect(self.update_buttons)
        self.button_status_signal.connect(self.update_button_status)

        # Subscribe to the multi level map data to get information about all the maps.
        self.multimap_subscriber = rospy.Subscriber("map_metadata", MultiLevelMapData,
                                                    self.process_multimap)
        self.levels = []
        self.current_level = None
        rospy.loginfo('level selector: subscribed to maps')

        # Subscribe to the current level we are on.
        self.status_subscriber = None

        # Create a service proxy to change the current level.
        self.level_selector_proxy = rospy.ServiceProxy("level_mux/change_current_level",
                                                       ChangeCurrentLevel)
        self.level_selector_proxy.wait_for_service()
        rospy.loginfo('level selector: found "level_mux/change_current_level" service')
Ejemplo n.º 27
0
    def __init__(self, popup_name, timeline, viewer_type, topics):
        super(TopicPopupWidget, self).__init__()
        self.setObjectName(popup_name)
        self.setWindowTitle(popup_name)

        layout = QVBoxLayout()
        self.setLayout(layout)

        self._timeline = timeline
        self._viewer_type = viewer_type
        self._topics = topics
        self._viewer = None
        self._is_listening = False
        self._connected = False  # True when the record bag is effectively loaded
Ejemplo n.º 28
0
    def __init__(self, node):
        super(SensorWidget, self).__init__()
        layout = QVBoxLayout(self)
        self.static_canvas = FigureCanvas(Figure(figsize=(5, 3)))
        layout.addWidget(self.static_canvas)

        self.ax = self.static_canvas.figure.subplots()
        self.ax.set_xlim(0, 50)
        self.ax.set_ylim(500, 1500)

        self.ax.set_title('Sensor Data')
        self.ax.set_xlabel('Time')
        self.ax.set_ylabel('Microstrain')
        self.ax.legend()
        self.ax.grid()

        self.sensor_data = []
        self.sensor_ref = None
        self._node = node
        self._node.create_subscription(Sensor, 'sensor_data',
                                       self.dataCallback, 10)
        self._node.create_subscription(SensorList, 'sensor_ref',
                                       self.refCallback, 10)
Ejemplo n.º 29
0
    def __init__(self, context):
        super(Simulation, self).__init__(context)
        # Give QObjects reasonable names
        self.setObjectName("AgimusSimulation")

        self._tfFrameEditors = []

        # Create QWidget
        self._widget = QWidget()
        self._layout = QVBoxLayout(self._widget)

        self.parseArguments(context)

        # 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)
 def process(self, action):
     """
     :param action: action to execute, ''QAction''
     :raises: when it doesn't recognice the action passed in, ''Exception''
     """
     if action == self._reset_timeline:
         self.timeline._timeline_frame.reset_timeline()
     elif action == self._play_all:
         self.timeline.toggle_play_all()
     elif action == self._publish_all:
         for topic in self.timeline._timeline_frame.topics:
             if not self.timeline.start_publishing(topic):
                 break
     elif action == self._publish_none:
         for topic in self.timeline._timeline_frame.topics:
             if not self.timeline.stop_publishing(topic):
                 break
     elif action == self._thumbnail_show_action:
         self.timeline._timeline_frame.set_renderers_active(True)
     elif action == self._thumbnail_hide_action:
         self.timeline._timeline_frame.set_renderers_active(False)
     elif action in self._thumbnail_actions:
         if self.timeline._timeline_frame.is_renderer_active(action.text()):
             self.timeline._timeline_frame.set_renderer_active(
                 action.text(), False)
         else:
             self.timeline._timeline_frame.set_renderer_active(
                 action.text(), True)
     elif action in self._topic_actions + self._type_actions:
         popup_name = action.parentWidget().title() + '__' + action.text()
         if popup_name not in self.timeline.popups:
             frame = QWidget()
             layout = QVBoxLayout()
             frame.setLayout(layout)
             frame.resize(640, 480)
             viewer_type = action.data()
             frame.setObjectName(popup_name)
             view = viewer_type(self.timeline, frame)
             self.timeline.popups.add(popup_name)
             self.timeline.get_context().add_widget(frame)
             self.timeline.add_view(action.parentWidget().title(), view,
                                    frame)
             frame.show()
     elif action in self._publish_actions:
         if self.timeline.is_publishing(action.text()):
             self.timeline.stop_publishing(action.text())
         else:
             self.timeline.start_publishing(action.text())
     else:
         raise Exception('Unknown action in TimelinePopupMenu.process')
Ejemplo n.º 31
0
    def __init__(self, parent):
        super(NodeSelection, self).__init__()
        self.parent_widget = parent
        self.selected_nodes = []
        self.setWindowTitle("Select the nodes you want to record")
        self.resize(500, 700)
        self.area = QScrollArea(self)
        self.main_widget = QWidget(self.area)
        self.ok_button = QPushButton("Done", self)
        self.ok_button.clicked.connect(self.onButtonClicked)
        self.ok_button.setEnabled(False)
        self.main_vlayout = QVBoxLayout(self)
        self.main_vlayout.addWidget(self.area)
        self.main_vlayout.addWidget(self.ok_button)
        self.setLayout(self.main_vlayout)

        self.selection_vlayout = QVBoxLayout(self)

        self.node_list = rosnode.get_node_names()
        self.node_list.sort()
        for node in self.node_list:
            self.addCheckBox(node)
        self.main_widget.setLayout(self.selection_vlayout)
        self.show()
Ejemplo n.º 32
0
    def __init__(self, parent, name, status, timeline):
        """
        :type status: DiagnosticStatus
        :param close_callback: When the instance of this class
                               (InspectorWindow) terminates, this callback gets
                               called.
        """
        #TODO(Isaac) UI construction that currently is done in this method,
        #            needs to be done in .ui file.

        super(InspectorWindow, self).__init__()
        self.setWindowTitle(name)
        self._name = name

        self.layout_vertical = QVBoxLayout(self)

        self.disp = StatusSnapshot(parent=self)

        self.layout_vertical.addWidget(self.disp, 1)

        if timeline is not None:
            self.timeline_pane = TimelinePane(self)
            self.timeline_pane.set_timeline(timeline, name)
            self.layout_vertical.addWidget(self.timeline_pane, 0)

            self.snapshot = QPushButton("Snapshot")
            self.snapshot.clicked.connect(self._take_snapshot)
            self.layout_vertical.addWidget(self.snapshot)

        self.snaps = []

        self.setLayout(self.layout_vertical)
        # TODO better to be configurable where to appear.
        self.resize(400, 600)
        self.show()
        self.message_updated(status)
Ejemplo n.º 33
0
    def __init__(self, parent):
        super(NodeSelection, self).__init__()
        self.parent_widget = parent
        self.selected_nodes = []
        self.setWindowTitle("Select the nodes you want to record")
        self.resize(500, 700)
        self.area = QScrollArea(self)
        self.main_widget = QWidget(self.area)
        self.ok_button = QPushButton("Done", self)
        self.ok_button.clicked.connect(self.onButtonClicked)
        self.ok_button.setEnabled(False)
        self.main_vlayout = QVBoxLayout(self)
        self.main_vlayout.addWidget(self.area)
        self.main_vlayout.addWidget(self.ok_button)
        self.setLayout(self.main_vlayout)

        self.selection_vlayout = QVBoxLayout(self)

        self.node_list = rosnode.get_node_names()
        self.node_list.sort()
        for node in self.node_list:
            self.addCheckBox(node)
        self.main_widget.setLayout(self.selection_vlayout)
        self.show()
Ejemplo n.º 34
0
    def __init__(self, bagFiles, parent=None):
        super(PlotDialogWidget, self).__init__()
        self.parent = parent
        self.bagFiles = bagFiles
        self.setWindowTitle("Add new Graph")
        self.layout = QVBoxLayout()
        self.resize(600, 400)

        # init the components
        self.tabWidget = QTabWidget()
        self.rawDataTab = RawDataTab(bagFiles, self)
        self.compareTab = CompareDataTab(bagFiles, self)
        self.diffTab = DiffTab(bagFiles, self)
        self.tabWidget.addTab(self.rawDataTab, "Raw Data Graphs")
        self.tabWidget.addTab(self.compareTab, "Evaluation Graphs")
        self.tabWidget.addTab(self.diffTab, "Difference Graphs")
        self.layout.addWidget(self.tabWidget)

        # init the start button
        startBtn = QPushButton("Start")
        startBtn.clicked.connect(self.startPressed)
        self.layout.addWidget(startBtn)

        self.setLayout(self.layout)
Ejemplo n.º 35
0
    def __init__(self, title, items, parent):
        super(ListDialog, self).__init__(parent)

        self._layout = QVBoxLayout()
        self._view_box = QGroupBox("Optional topics")
        self._view_box_layout = QVBoxLayout(self._view_box)
        self._list_widget = QListWidget()
        self._view_box_layout.addWidget(self._list_widget)
        self._button_box = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Close)
        self._button_box.accepted.connect(self.save)
        self._button_box.rejected.connect(self.reject)

        self.setWindowTitle(title)

        self.create_list_widget(items)

        self._layout.addWidget(self._view_box)
        self._layout.addWidget(self._button_box)
        self.setLayout(self._layout)

        # createConnections
        self._list_widget.itemChanged.connect(self.highlight_checked)

        self.selected_items = []
Ejemplo n.º 36
0
    def __init__(self, node):
        super(RewardWidget, self).__init__()
        layout = QVBoxLayout(self)
        self.static_canvas = FigureCanvas(Figure(figsize=(5, 3)))
        layout.addWidget(self.static_canvas)

        self.ax = self.static_canvas.figure.subplots()
        self.ax.set_xlim(0, 50)
        # self.ax.set_ylim(0,5)
        self.ax.set_title('Reward Functions')
        self.ax.set_xlabel('Time')
        self.ax.set_ylabel('Reward')
        self.ax.legend()
        self.ax.grid()

        self.reward_total = []
        self.reward_total_var = []

        self.reward_state = []
        self.reward_state_var = []

        self.reward_control = []
        self.reward_control_var = []

        self.reward_policy = []
        self.reward_policy_var = []

        self.reward_outputerror = []
        self.reward_outputerror_var = []

        self.reward_types = []

        self.topic_name = 'reward_estimate'
        self._node = node
        self._node.create_subscription(Reward, self.topic_name,
                                       self.ReceivedCallback, 10)
Ejemplo n.º 37
0
    def __init__(self, rospack):
        """"""
        super(ParameditWidget, self).__init__()

        ui_file = os.path.join(rospack.get_path('rqt_reconfigure'),
                               'resource', 'paramedit_pane.ui')
        loadUi(ui_file, self, {'ParameditWidget': ParameditWidget})

        self._dynreconf_clients = OrderedDict()

        # Adding the list of Items
        self.vlayout = QVBoxLayout(self.scrollarea_holder_widget)

        #self._set_index_widgets(self.listview, paramitems_dict) # causes error
        self.destroyed.connect(self.close)
Ejemplo n.º 38
0
class NodeSelection(QWidget):
    def __init__(self, parent):
        super(NodeSelection, self).__init__()
        self.parent_widget = parent
        self.selected_nodes = []
        self.setWindowTitle("Select the nodes you want to record")
        self.resize(500, 700)
        self.area = QScrollArea(self)
        self.main_widget = QWidget(self.area)
        self.ok_button = QPushButton("Done", self)
        self.ok_button.clicked.connect(self.onButtonClicked)
        self.ok_button.setEnabled(False)
        self.main_vlayout = QVBoxLayout(self)
        self.main_vlayout.addWidget(self.area)
        self.main_vlayout.addWidget(self.ok_button)
        self.setLayout(self.main_vlayout)

        self.selection_vlayout = QVBoxLayout(self)

        self.node_list = rosnode.get_node_names()
        self.node_list.sort()
        for node in self.node_list:
            self.addCheckBox(node)
        self.main_widget.setLayout(self.selection_vlayout)
        self.show()

    def addCheckBox(self, node):
        item = QCheckBox(node, self)
        item.stateChanged.connect(lambda x: self.updateNode(x, node))
        self.selection_vlayout.addWidget(item)

    def updateNode(self, state, node):
        if state == Qt.Checked:
            self.selected_nodes.append(node)
        else:
            self.selected_nodes.remove(node)
        if len(self.selected_nodes) > 0:
            self.ok_button.setEnabled(True)
        else:
            self.ok_button.setEnabled(False)

    def onButtonClicked(self):
        master = rosgraph.Master('rqt_bag_recorder')
        state = master.getSystemState()
        subs = [t for t, l in state[1]
                if len([node_name for node_name in self.selected_nodes if node_name in l]) > 0]
        for topic in subs:
            self.parent_widget.changeTopicCheckState(topic, Qt.Checked)
            self.parent_widget.updateList(Qt.Checked, topic)
        self.close()
Ejemplo n.º 39
0
    def __init__(self, parent, name, status, timeline):
        """
        :type status: DiagnosticStatus
        :param close_callback: When the instance of this class
                               (InspectorWindow) terminates, this callback gets
                               called.
        """
        #TODO(Isaac) UI construction that currently is done in this method,
        #            needs to be done in .ui file.

        super(InspectorWindow, self).__init__()
        self.setWindowTitle(name)
        self._name = name

        self.layout_vertical = QVBoxLayout(self)

        self.disp = StatusSnapshot(parent=self)

        self.layout_vertical.addWidget(self.disp, 1)

        if timeline is not None:
            self.timeline_pane = TimelinePane(self)
            self.timeline_pane.set_timeline(timeline, name)
            self.layout_vertical.addWidget(self.timeline_pane, 0)

            self.snapshot = QPushButton("Snapshot")
            self.snapshot.clicked.connect(self._take_snapshot)
            self.layout_vertical.addWidget(self.snapshot)

        self.snaps = []

        self.setLayout(self.layout_vertical)
        # TODO better to be configurable where to appear.
        self.resize(400, 600)
        self.show()
        self.message_updated(status)
Ejemplo n.º 40
0
    def __init__(self, context):
        super(Top, self).__init__(context)
        # Give QObjects reasonable names
        self.setObjectName('Top')

        # 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

        self._selected_node = ''
        self._selected_node_lock = RLock()

        # Setup the toolbar
        self._toolbar = QToolBar()
        self._filter_box = QLineEdit()
        self._regex_box  = QCheckBox()
        self._regex_box.setText('regex')
        self._toolbar.addWidget(QLabel('Filter'))
        self._toolbar.addWidget(self._filter_box)
        self._toolbar.addWidget(self._regex_box)

        self._filter_box.returnPressed.connect(self.update_filter)
        self._regex_box.stateChanged.connect(self.update_filter)

        # Create a container widget and give it a layout
        self._container = QWidget()
        self._container.setWindowTitle('Process Monitor')
        self._layout    = QVBoxLayout()
        self._container.setLayout(self._layout)

        self._layout.addWidget(self._toolbar)

        # Create the table widget
        self._table_widget = QTreeWidget()
        self._table_widget.setObjectName('TopTable')
        self._table_widget.setColumnCount(len(self.NODE_LABELS))
        self._table_widget.setHeaderLabels(self.NODE_LABELS)
        self._table_widget.itemClicked.connect(self._tableItemClicked)
        self._table_widget.setSortingEnabled(True)
        self._table_widget.setAlternatingRowColors(True)

        self._layout.addWidget(self._table_widget)
        context.add_widget(self._container)

        # Add a button for killing nodes
        self._kill_button = QPushButton('Kill Node')
        self._layout.addWidget(self._kill_button)
        self._kill_button.clicked.connect(self._kill_node)

        # Update twice since the first cpu% lookup will always return 0
        self.update_table()
        self.update_table()

        self._table_widget.resizeColumnToContents(0)

        # Start a timer to trigger updates
        self._update_timer = QTimer()
        self._update_timer.setInterval(1000)
        self._update_timer.timeout.connect(self.update_table)
        self._update_timer.start()
Ejemplo n.º 41
0
class LevelSelectorPlugin(Plugin):

    button_signal = pyqtSignal()
    button_status_signal = pyqtSignal()

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

        # Create QWidget
        self._widget = QWidget()
        self._widget.setFont(QFont("Times", 15, QFont.Bold))
        self._button_layout = QVBoxLayout(self._widget)

        self.buttons = []
        self.text_label = QLabel("Waiting for MultiLevelMapData...", self._widget)
        self._button_layout.addWidget(self.text_label)

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

        self.button_signal.connect(self.update_buttons)
        self.button_status_signal.connect(self.update_button_status)

        # Subscribe to the multi level map data to get information about all the maps.
        self.multimap_subscriber = rospy.Subscriber("map_metadata", MultiLevelMapData,
                                                    self.process_multimap)
        self.levels = []
        self.current_level = None
        rospy.loginfo('level selector: subscribed to maps')

        # Subscribe to the current level we are on.
        self.status_subscriber = None

        # Create a service proxy to change the current level.
        self.level_selector_proxy = rospy.ServiceProxy("level_mux/change_current_level",
                                                       ChangeCurrentLevel)
        self.level_selector_proxy.wait_for_service()
        rospy.loginfo('level selector: found "level_mux/change_current_level" service')

    def process_multimap(self, msg):
        """ Map metadata topic callback. """
        rospy.loginfo('level selector: map metadata received.')
        self.levels = msg.levels
        # update level buttons in the selection window
        self.button_signal.emit()

    def update_buttons(self):
        """ Update buttons in Qt window. """
        rospy.loginfo('level selector: update_buttons called')
        self.clean()
        for index, level in enumerate(self.levels):
            button = QPushButton(level.level_id, self._widget)
            button.clicked[bool].connect(self.handle_button)
            button.setCheckable(True)
            self._button_layout.addWidget(button)
            self.buttons.append(button)

        # Subscribe to the current level we are on.
        if self.status_subscriber is None:
            self.status_subscriber = rospy.Subscriber("level_mux/current_level",
                                                      LevelMetaData,
                                                      self.process_level_status)

    def update_button_status(self):
        """ Update button status Qt push button callback. """
        rospy.loginfo('level selector: update_button_status')
        if not self.buttons or not self.current_level:
            rospy.logwarn('level selector: current level not available')
            return
        rospy.logdebug('buttons: ' + str(self.buttons))
        for index, level in enumerate(self.levels):
            rospy.logdebug('level[' + str(index) + ']: ' + str(level.level_id))
            if self.current_level == level.level_id:
                self.buttons[index].setChecked(True)
            else:
                self.buttons[index].setChecked(False)

    def process_level_status(self, msg):
        """ level_mux/current_level topic callback. """
        rospy.loginfo('level selector: current_level topic message received')
        level_found = False
        for level in self.levels:
            if msg.level_id == level.level_id:
                self.current_level = level.level_id
                level_found = True
                break
        if not level_found:
            self.current_level = None
        self.button_status_signal.emit()

    def handle_button(self):
        source = self.sender()

        if source.text() == self.current_level:
            source.setChecked(True)
            return

        # Construct a identity pose. The level selector cannot be used
        # to choose the initialpose, as it does not have the interface
        # for specifying the position. The position should be
        # specified via rviz.
        origin_pose = PoseWithCovarianceStamped()
        origin_pose.header.frame_id = frameIdFromLevelId(source.text())
        origin_pose.pose.pose.orientation.w = 1    # Makes the origin quaternion valid.
        origin_pose.pose.covariance[0] = 1.0
        origin_pose.pose.covariance[7] = 1.0
        origin_pose.pose.covariance[14] = 1.0
        origin_pose.pose.covariance[21] = 1.0
        origin_pose.pose.covariance[28] = 1.0
        origin_pose.pose.covariance[35] = 1.0

        # Don't actually publish the initial pose via the level
        # selector. It doesn't know any better.
        self.level_selector_proxy(source.text(), False, origin_pose)

    def clean(self):
        while self._button_layout.count():
            item = self._button_layout.takeAt(0)
            item.widget().deleteLater()

    def save_settings(self, plugin_settings, instance_settings):
        pass

    def restore_settings(self, plugin_settings, instance_settings):
        pass
class JointStatePublisherGui(QWidget):
    sliderUpdateTrigger = Signal()

    def __init__(self, title, jsp, num_rows=0):
        super(JointStatePublisherGui, self).__init__()
        self.jsp = jsp
        self.joint_map = {}
        self.vlayout = QVBoxLayout(self)
        self.gridlayout = QGridLayout()
        font = QFont("Helvetica", 9, QFont.Bold)

        ### Generate sliders ###
        sliders = []
        for name in self.jsp.joint_list:
            if name not in self.jsp.free_joints:
                continue
            joint = self.jsp.free_joints[name]

            if joint['min'] == joint['max']:
                continue

            joint_layout = QVBoxLayout()
            row_layout = QHBoxLayout()

            label = QLabel(name)
            label.setFont(font)
            row_layout.addWidget(label)
            display = QLineEdit("0.00")
            display.setAlignment(Qt.AlignRight)
            display.setFont(font)
            display.setReadOnly(True)
            row_layout.addWidget(display)

            joint_layout.addLayout(row_layout)

            slider = QSlider(Qt.Horizontal)

            slider.setFont(font)
            slider.setRange(0, RANGE)
            slider.setValue(RANGE/2)

            joint_layout.addWidget(slider)

            self.joint_map[name] = {'slidervalue': 0, 'display': display,
                                    'slider': slider, 'joint': joint}
            # Connect to the signal provided by QSignal
            slider.valueChanged.connect(self.onValueChanged)
            sliders.append(joint_layout)

        # Determine number of rows to be used in grid
        self.num_rows = num_rows
        # if desired num of rows wasn't set, default behaviour is a vertical layout
        if self.num_rows == 0:
            self.num_rows = len(sliders)  # equals VBoxLayout
        # Generate positions in grid and place sliders there
        self.positions = self.generate_grid_positions(len(sliders), self.num_rows)
        for item, pos in zip(sliders, self.positions):
            self.gridlayout.addLayout(item, *pos)

        # Set zero positions read from parameters
        self.center()

        # Synchronize slider and displayed value
        self.sliderUpdate(None)

        # Set up a signal for updating the sliders based on external joint info
        self.sliderUpdateTrigger.connect(self.updateSliders)

        self.vlayout.addLayout(self.gridlayout)

        # Buttons for randomizing and centering sliders and
        # Spinbox for on-the-fly selecting number of rows
        self.randbutton = QPushButton('Randomize', self)
        self.randbutton.clicked.connect(self.randomize_event)
        self.vlayout.addWidget(self.randbutton)
        self.ctrbutton = QPushButton('Center', self)
        self.ctrbutton.clicked.connect(self.center_event)
        self.vlayout.addWidget(self.ctrbutton)
        self.maxrowsupdown = QSpinBox()
        self.maxrowsupdown.setMinimum(1)
        self.maxrowsupdown.setMaximum(len(sliders))
        self.maxrowsupdown.setValue(self.num_rows)
        self.maxrowsupdown.lineEdit().setReadOnly(True)  # don't edit it by hand to avoid weird resizing of window
        self.maxrowsupdown.valueChanged.connect(self.reorggrid_event)
        self.vlayout.addWidget(self.maxrowsupdown)

    @pyqtSlot(int)
    def onValueChanged(self, event):
        # A slider value was changed, but we need to change the joint_info metadata.
        for name, joint_info in self.joint_map.items():
            joint_info['slidervalue'] = joint_info['slider'].value()
            joint = joint_info['joint']
            joint['position'] = self.sliderToValue(joint_info['slidervalue'], joint)
            joint_info['display'].setText("%.2f" % joint['position'])

    @pyqtSlot()
    def updateSliders(self):
        self.update_sliders()

    def update_sliders(self):
        for name, joint_info in self.joint_map.items():
            joint = joint_info['joint']
            joint_info['slidervalue'] = self.valueToSlider(joint['position'],
                                                           joint)
            joint_info['slider'].setValue(joint_info['slidervalue'])

    def center_event(self, event):
        self.center()

    def center(self):
        rospy.loginfo("Centering")
        for name, joint_info in self.joint_map.items():
            joint = joint_info['joint']
            joint_info['slider'].setValue(self.valueToSlider(joint['zero'], joint))

    def reorggrid_event(self, event):
        self.reorganize_grid(event)

    def reorganize_grid(self, number_of_rows):
        self.num_rows = number_of_rows

        # Remove items from layout (won't destroy them!)
        items = []
        for pos in self.positions:
            item = self.gridlayout.itemAtPosition(*pos)
            items.append(item)
            self.gridlayout.removeItem(item)

        # Generate new positions for sliders and place them in their new spots
        self.positions = self.generate_grid_positions(len(items), self.num_rows)
        for item, pos in zip(items, self.positions):
            self.gridlayout.addLayout(item, *pos)

    def generate_grid_positions(self, num_items, num_rows):
        if num_rows==0:
          return []
        positions = [(y, x) for x in range(int((math.ceil(float(num_items) / num_rows)))) for y in range(num_rows)]
        positions = positions[:num_items]
        return positions

    def randomize_event(self, event):
        self.randomize()

    def randomize(self):
        rospy.loginfo("Randomizing")
        for name, joint_info in self.joint_map.items():
            joint = joint_info['joint']
            joint_info['slider'].setValue(
                    self.valueToSlider(random.uniform(joint['min'], joint['max']), joint))

    def sliderUpdate(self, event):
        for name, joint_info in self.joint_map.items():
            joint_info['slidervalue'] = joint_info['slider'].value()
        self.update_sliders()

    def valueToSlider(self, value, joint):
        return (value - joint['min']) * float(RANGE) / (joint['max'] - joint['min'])

    def sliderToValue(self, slider, joint):
        pctvalue = slider / float(RANGE)
        return joint['min'] + (joint['max']-joint['min']) * pctvalue
    def __init__(self, title, jsp, num_rows=0):
        super(JointStatePublisherGui, self).__init__()
        self.jsp = jsp
        self.joint_map = {}
        self.vlayout = QVBoxLayout(self)
        self.gridlayout = QGridLayout()
        font = QFont("Helvetica", 9, QFont.Bold)

        ### Generate sliders ###
        sliders = []
        for name in self.jsp.joint_list:
            if name not in self.jsp.free_joints:
                continue
            joint = self.jsp.free_joints[name]

            if joint['min'] == joint['max']:
                continue

            joint_layout = QVBoxLayout()
            row_layout = QHBoxLayout()

            label = QLabel(name)
            label.setFont(font)
            row_layout.addWidget(label)
            display = QLineEdit("0.00")
            display.setAlignment(Qt.AlignRight)
            display.setFont(font)
            display.setReadOnly(True)
            row_layout.addWidget(display)

            joint_layout.addLayout(row_layout)

            slider = QSlider(Qt.Horizontal)

            slider.setFont(font)
            slider.setRange(0, RANGE)
            slider.setValue(RANGE/2)

            joint_layout.addWidget(slider)

            self.joint_map[name] = {'slidervalue': 0, 'display': display,
                                    'slider': slider, 'joint': joint}
            # Connect to the signal provided by QSignal
            slider.valueChanged.connect(self.onValueChanged)
            sliders.append(joint_layout)

        # Determine number of rows to be used in grid
        self.num_rows = num_rows
        # if desired num of rows wasn't set, default behaviour is a vertical layout
        if self.num_rows == 0:
            self.num_rows = len(sliders)  # equals VBoxLayout
        # Generate positions in grid and place sliders there
        self.positions = self.generate_grid_positions(len(sliders), self.num_rows)
        for item, pos in zip(sliders, self.positions):
            self.gridlayout.addLayout(item, *pos)

        # Set zero positions read from parameters
        self.center()

        # Synchronize slider and displayed value
        self.sliderUpdate(None)

        # Set up a signal for updating the sliders based on external joint info
        self.sliderUpdateTrigger.connect(self.updateSliders)

        self.vlayout.addLayout(self.gridlayout)

        # Buttons for randomizing and centering sliders and
        # Spinbox for on-the-fly selecting number of rows
        self.randbutton = QPushButton('Randomize', self)
        self.randbutton.clicked.connect(self.randomize_event)
        self.vlayout.addWidget(self.randbutton)
        self.ctrbutton = QPushButton('Center', self)
        self.ctrbutton.clicked.connect(self.center_event)
        self.vlayout.addWidget(self.ctrbutton)
        self.maxrowsupdown = QSpinBox()
        self.maxrowsupdown.setMinimum(1)
        self.maxrowsupdown.setMaximum(len(sliders))
        self.maxrowsupdown.setValue(self.num_rows)
        self.maxrowsupdown.lineEdit().setReadOnly(True)  # don't edit it by hand to avoid weird resizing of window
        self.maxrowsupdown.valueChanged.connect(self.reorggrid_event)
        self.vlayout.addWidget(self.maxrowsupdown)
Ejemplo n.º 44
0
    def __init__(self, updater, config, nodename):
        '''
        :param config:
        :type config: Dictionary? defined in dynamic_reconfigure.client.Client
        :type nodename: str
        '''

        super(GroupWidget, self).__init__()
        self.state = config['state']
        self.param_name = config['name']
        self._toplevel_treenode_name = nodename

        # TODO: .ui file needs to be back into usage in later phase.
#        ui_file = os.path.join(rp.get_path('rqt_reconfigure'),
#                               'resource', 'singlenode_parameditor.ui')
#        loadUi(ui_file, self)

        verticalLayout = QVBoxLayout(self)
        verticalLayout.setContentsMargins(QMargins(0, 0, 0, 0))

        _widget_nodeheader = QWidget()
        _h_layout_nodeheader = QHBoxLayout(_widget_nodeheader)
        _h_layout_nodeheader.setContentsMargins(QMargins(0, 0, 0, 0))

        self.nodename_qlabel = QLabel(self)
        font = QFont('Trebuchet MS, Bold')
        font.setUnderline(True)
        font.setBold(True)

        # Button to close a node.
        _icon_disable_node = QIcon.fromTheme('window-close')
        _bt_disable_node = QPushButton(_icon_disable_node, '', self)
        _bt_disable_node.setToolTip('Hide this node')
        _bt_disable_node_size = QSize(36, 24)
        _bt_disable_node.setFixedSize(_bt_disable_node_size)
        _bt_disable_node.pressed.connect(self._node_disable_bt_clicked)

        _h_layout_nodeheader.addWidget(self.nodename_qlabel)
        _h_layout_nodeheader.addWidget(_bt_disable_node)

        self.nodename_qlabel.setAlignment(Qt.AlignCenter)
        font.setPointSize(10)
        self.nodename_qlabel.setFont(font)
        grid_widget = QWidget(self)
        self.grid = QFormLayout(grid_widget)
        verticalLayout.addWidget(_widget_nodeheader)
        verticalLayout.addWidget(grid_widget, 1)
        # Again, these UI operation above needs to happen in .ui file.

        self.tab_bar = None  # Every group can have one tab bar
        self.tab_bar_shown = False

        self.updater = updater

        self.editor_widgets = []
        self._param_names = []

        self._create_node_widgets(config)

        rospy.logdebug('Groups node name={}'.format(nodename))
        self.nodename_qlabel.setText(nodename)
Ejemplo n.º 45
0
class TopicSelection(QWidget):

    recordSettingsSelected = Signal(bool, list)

    def __init__(self):
        super(TopicSelection, self).__init__()
        master = rosgraph.Master('rqt_bag_recorder')
        self.setWindowTitle("Select the topics you want to record")
        self.resize(500, 700)

        self.topic_list = []
        self.selected_topics = []
        self.items_list = []

        self.area = QScrollArea(self)
        self.main_widget = QWidget(self.area)
        self.ok_button = QPushButton("Record", self)
        self.ok_button.clicked.connect(self.onButtonClicked)
        self.ok_button.setEnabled(False)

        self.main_vlayout = QVBoxLayout(self)
        self.main_vlayout.addWidget(self.area)
        self.main_vlayout.addWidget(self.ok_button)
        self.setLayout(self.main_vlayout)

        self.selection_vlayout = QVBoxLayout(self)
        self.item_all = QCheckBox("All", self)
        self.item_all.stateChanged.connect(self.updateList)
        self.selection_vlayout.addWidget(self.item_all)
        topic_data_list = master.getPublishedTopics('')
        topic_data_list.sort()
        for topic, datatype in topic_data_list:
            self.addCheckBox(topic)

        self.main_widget.setLayout(self.selection_vlayout)

        self.area.setWidget(self.main_widget)
        self.show()

    def addCheckBox(self, topic):
        self.topic_list.append(topic)
        item = QCheckBox(topic, self)
        item.stateChanged.connect(lambda x: self.updateList(x,topic))
        self.items_list.append(item)
        self.selection_vlayout.addWidget(item)


    def updateList(self, state, topic = None):
        if topic is None: # The "All" checkbox was checked / unchecked
            if state == Qt.Checked:
                self.item_all.setTristate(False)
                for item in self.items_list:
                    if item.checkState() == Qt.Unchecked:
                        item.setCheckState(Qt.Checked)
            elif state == Qt.Unchecked:
                self.item_all.setTristate(False)
                for item in self.items_list:
                    if item.checkState() == Qt.Checked:
                        item.setCheckState(Qt.Unchecked)
        else:
            if state == Qt.Checked:
                self.selected_topics.append(topic)
            else:
                self.selected_topics.remove(topic)
                if self.item_all.checkState()==Qt.Checked:
                    self.item_all.setCheckState(Qt.PartiallyChecked)

        if self.selected_topics == []:
            self.ok_button.setEnabled(False)
        else:
            self.ok_button.setEnabled(True)

    def onButtonClicked(self):
        self.close()
        self.recordSettingsSelected.emit((self.item_all.checkState() == Qt.Checked), self.selected_topics)
Ejemplo n.º 46
0
    def __init__(self, context, node=None):
        """
        This class is intended to be called by rqt plugin framework class.
        Currently (12/12/2012) the whole widget is splitted into 2 panes:
        one on left allows you to choose the node(s) you work on. Right side
        pane lets you work with the parameters associated with the node(s) you
        select on the left.

        (12/27/2012) Despite the pkg name is changed to rqt_reconfigure to
        reflect the available functionality, file & class names remain
        'param', expecting all the parameters will become handle-able.
        """

        super(ParamWidget, self).__init__()
        self.setObjectName(self._TITLE_PLUGIN)
        self.setWindowTitle(self._TITLE_PLUGIN)

        rp = rospkg.RosPack()

        #TODO: .ui file needs to replace the GUI components declaration
        #            below. For unknown reason, referring to another .ui files
        #            from a .ui that is used in this class failed. So for now,
        #            I decided not use .ui in this class.
        #            If someone can tackle this I'd appreciate.
        _hlayout_top = QHBoxLayout(self)
        _hlayout_top.setContentsMargins(QMargins(0, 0, 0, 0))
        self._splitter = QSplitter(self)
        _hlayout_top.addWidget(self._splitter)

        _vlayout_nodesel_widget = QWidget()
        _vlayout_nodesel_side = QVBoxLayout()
        _hlayout_filter_widget = QWidget(self)
        _hlayout_filter = QHBoxLayout()
        self._text_filter = TextFilter()
        self.filter_lineedit = TextFilterWidget(self._text_filter, rp)
        self.filterkey_label = QLabel("&Filter key:")
        self.filterkey_label.setBuddy(self.filter_lineedit)
        _hlayout_filter.addWidget(self.filterkey_label)
        _hlayout_filter.addWidget(self.filter_lineedit)
        _hlayout_filter_widget.setLayout(_hlayout_filter)
        self._nodesel_widget = NodeSelectorWidget(self, rp, self.sig_sysmsg)
        _vlayout_nodesel_side.addWidget(_hlayout_filter_widget)
        _vlayout_nodesel_side.addWidget(self._nodesel_widget)
        _vlayout_nodesel_side.setSpacing(1)
        _vlayout_nodesel_widget.setLayout(_vlayout_nodesel_side)

        reconf_widget = ParameditWidget(rp)

        self._splitter.insertWidget(0, _vlayout_nodesel_widget)
        self._splitter.insertWidget(1, reconf_widget)
        # 1st column, _vlayout_nodesel_widget, to minimize width.
        # 2nd col to keep the possible max width.
        self._splitter.setStretchFactor(0, 0)
        self._splitter.setStretchFactor(1, 1)

        # Signal from paramedit widget to node selector widget.
        reconf_widget.sig_node_disabled_selected.connect(
                                       self._nodesel_widget.node_deselected)
        # Pass name of node to editor widget
        self._nodesel_widget.sig_node_selected.connect(
                                                     reconf_widget.show_reconf)

        if not node:
            title = self._TITLE_PLUGIN
        else:
            title = self._TITLE_PLUGIN + ' %s' % node
        self.setObjectName(title)

        #Connect filter signal-slots.
        self._text_filter.filter_changed_signal.connect(
                                            self._filter_key_changed)

        # Open any clients indicated from command line
        self.sig_selected.connect(self._nodesel_widget.node_selected)
        for rn in [rospy.resolve_name(c) for c in context.argv()]:
            if rn in self._nodesel_widget.get_paramitems():
                self.sig_selected.emit(rn)
            else:
                rospy.logwarn('Could not find a dynamic reconfigure client named \'%s\'', str(rn))
Ejemplo n.º 47
0
class ParameditWidget(QWidget):
    """
    This class represents a pane where parameter editor widgets of multiple
    nodes are shown. In rqt_reconfigure, this pane occupies right half of the
    entire visible area.
    """

    # public signal
    sig_node_disabled_selected = Signal(str)

    def __init__(self, rospack):
        """"""
        super(ParameditWidget, self).__init__()

        ui_file = os.path.join(rospack.get_path('rqt_reconfigure'),
                               'resource', 'paramedit_pane.ui')
        loadUi(ui_file, self, {'ParameditWidget': ParameditWidget})

        self._dynreconf_clients = OrderedDict()

        # Adding the list of Items
        self.vlayout = QVBoxLayout(self.scrollarea_holder_widget)

        #self._set_index_widgets(self.listview, paramitems_dict) # causes error
        self.destroyed.connect(self.close)

    def _set_index_widgets(self, view, paramitems_dict):
        """
        @deprecated: Causes error
        """
        i = 0
        for p in paramitems_dict:
            view.setIndexWidget(i, p)
            i += 1

    def show_reconf(self, dynreconf_widget):
        """
        Callback when user chooses a node.

        @param dynreconf_widget:
        """
        node_grn = dynreconf_widget.get_node_grn()
        rospy.logdebug('ParameditWidget.show str(node_grn)=%s', str(node_grn))

        if not node_grn in self._dynreconf_clients.keys():
            # Add dynreconf widget if there isn't already one.

            # Client gets renewed every time different node_grn was clicked.

            self._dynreconf_clients.__setitem__(node_grn, dynreconf_widget)
            self.vlayout.addWidget(dynreconf_widget)
            dynreconf_widget.sig_node_disabled_selected.connect(
                                                           self._node_disabled)

        else:  # If there has one already existed, remove it.
            self._remove_node(node_grn)
            #LayoutUtil.clear_layout(self.vlayout)

            # Re-add the rest of existing items to layout.
            #for k, v in self._dynreconf_clients.iteritems():
            #    rospy.loginfo('added to layout k={} v={}'.format(k, v))
            #    self.vlayout.addWidget(v)

        # Add color to alternate the rim of the widget.
        LayoutUtil.alternate_color(self._dynreconf_clients.itervalues(),
                                   [self.palette().background().color().lighter(125),
                                    self.palette().background().color().darker(125)])

    def close(self):
        for dc in self._dynreconf_clients:
            # Clear out the old widget
            dc.close()
            dc = None

            self._paramedit_scrollarea.deleteLater()

    def filter_param(self, filter_key):
        """
        :type filter_key:
        """

        #TODO Pick nodes that match filter_key.

        #TODO For the nodes that are kept in previous step, call
        #     DynreconfWidget.filter_param for all of its existing
        #     instances.
        pass

    def _remove_node(self, node_grn):
        try:
            i = self._dynreconf_clients.keys().index(node_grn)
        except ValueError:
            # ValueError occurring here means that the specified key is not
            # found, most likely already removed, which is possible in the
            # following situation/sequence:
            #
            # Node widget on ParameditWidget removed by clicking disable button
            # --> Node deselected on tree widget gets updated
            # --> Tree widget detects deselection
            # --> Tree widget emits deselection signal, which is captured by
            #     ParameditWidget's slot. Thus reaches this method again.
            return

        item = self.vlayout.itemAt(i)
        if isinstance(item, QWidgetItem):
                item.widget().close()
        w = self._dynreconf_clients.pop(node_grn)

        rospy.logdebug('popped={} Len of left clients={}'.format(
                                            w, len(self._dynreconf_clients)))

    def _node_disabled(self, node_grn):
        rospy.logdebug('paramedit_w _node_disabled grn={}'.format(node_grn))

        # Signal to notify other GUI components (eg. nodes tree pane) that
        # a node widget is disabled.
        self.sig_node_disabled_selected.emit(node_grn)

        # Remove the selected node widget from the internal list of nodes.
        self._remove_node(node_grn)
Ejemplo n.º 48
0
class NavViewWidget(QWidget):

    def __init__(self, map_topic='/map',
                 paths=['/move_base/NavFn/plan', '/move_base/TrajectoryPlannerROS/local_plan'],
                 polygons=['/move_base/local_costmap/robot_footprint']):
        super(NavViewWidget, self).__init__()
        self._layout = QVBoxLayout()
        self._button_layout = QHBoxLayout()

        self.setAcceptDrops(True)
        self.setWindowTitle('Navigation Viewer')

        self.paths = paths
        self.polygons = polygons
        self.map = map_topic
        self._tf = tf.TransformListener()

        self._nav_view = NavView(map_topic, paths, polygons, tf = self._tf, parent = self)

        self._set_pose = QPushButton('Set Pose')
        self._set_pose.clicked.connect(self._nav_view.pose_mode)
        self._set_goal = QPushButton('Set Goal')
        self._set_goal.clicked.connect(self._nav_view.goal_mode)

        self._button_layout.addWidget(self._set_pose)
        self._button_layout.addWidget(self._set_goal)

        self._layout.addLayout(self._button_layout)

        self._layout.addWidget(self._nav_view)

        self.setLayout(self._layout)

    def dragEnterEvent(self, e):
        if not e.mimeData().hasText():
            if not hasattr(e.source(), 'selectedItems') or len(e.source().selectedItems()) == 0:
                qWarning('NavView.dragEnterEvent(): not hasattr(event.source(), selectedItems) or len(event.source().selectedItems()) == 0')
                return
            item = e.source().selectedItems()[0]
            topic_name = item.data(0, Qt.UserRole)
            if topic_name == None:
                qWarning('NavView.dragEnterEvent(): not hasattr(item, ros_topic_name_)')
                return

        else:
            topic_name = str(e.mimeData().text())

        if accepted_topic(topic_name):
            e.accept()
            e.acceptProposedAction()

    def dropEvent(self, e):
        if e.mimeData().hasText():
            topic_name = str(e.mimeData().text())
        else:
            droped_item = e.source().selectedItems()[0]
            topic_name = str(droped_item.data(0, Qt.UserRole))

        topic_type, array = get_field_type(topic_name)
        if not array:
            if topic_type is OccupancyGrid:
                self.map = topic_name

                # Swap out the nav view for one with the new topics
                self._nav_view.close()
                self._nav_view = NavView(self.map, self.paths, self.polygons, self._tf, self)
                self._layout.addWidget(self._nav_view)
            elif topic_type is Path:
                self.paths.append(topic_name)
                self._nav_view.add_path(topic_name)
            elif topic_type is PolygonStamped:
                self.polygons.append(topic_name)
                self._nav_view.add_polygon(topic_name)

    def save_settings(self, plugin_settings, instance_settings):
        self._nav_view.save_settings(plugin_settings, instance_settings)

    def restore_settings(self, plugin_settings, instance_settings):
        self._nav_view.restore_settings(plugin_settings, instance_settings)
Ejemplo n.º 49
0
class InspectorWindow(QWidget):
    closed = Signal(str)

    def __init__(self, parent, name, status, timeline):
        """
        :type status: DiagnosticStatus
        :param close_callback: When the instance of this class
                               (InspectorWindow) terminates, this callback gets
                               called.
        """
        #TODO(Isaac) UI construction that currently is done in this method,
        #            needs to be done in .ui file.

        super(InspectorWindow, self).__init__()
        self.setWindowTitle(name)
        self._name = name

        self.layout_vertical = QVBoxLayout(self)

        self.disp = StatusSnapshot(parent=self)

        self.layout_vertical.addWidget(self.disp, 1)

        if timeline is not None:
            self.timeline_pane = TimelinePane(self)
            self.timeline_pane.set_timeline(timeline, name)
            self.layout_vertical.addWidget(self.timeline_pane, 0)

            self.snapshot = QPushButton("Snapshot")
            self.snapshot.clicked.connect(self._take_snapshot)
            self.layout_vertical.addWidget(self.snapshot)

        self.snaps = []

        self.setLayout(self.layout_vertical)
        # TODO better to be configurable where to appear.
        self.resize(400, 600)
        self.show()
        self.message_updated(status)

    def closeEvent(self, event):
        """ called when this window is closed

        Calls close on all snapshots, and emits the closed signal
        """
        # TODO: are snapshots kept around even after they're closed?
        #       this appears to work even if the user closes some snapshots,
        #       and they're still left in the internal array
        for snap in self.snaps:
            snap.close()
        self.closed.emit(self._name)

    @Slot(DiagnosticArray)
    def message_updated(self, msg):
        status = util.get_status_by_name(msg, self._name)
        scroll_value = self.disp.verticalScrollBar().value()

        rospy.logdebug('InspectorWin message_updated')

        self.status = status
        self.disp.write_status.emit(status)

        if self.disp.verticalScrollBar().maximum() < scroll_value:
            scroll_value = self.disp.verticalScrollBar().maximum()
        self.disp.verticalScrollBar().setValue(scroll_value)

    def _take_snapshot(self):
        snap = StatusSnapshot(status=self.status)
        self.snaps.append(snap)
Ejemplo n.º 50
0
class Top(Plugin):

    NODE_FIELDS   = [             'pid', 'get_cpu_percent', 'get_memory_percent', 'get_num_threads']
    OUT_FIELDS    = ['node_name', 'pid', 'cpu_percent',     'memory_percent',     'num_threads'    ]
    FORMAT_STRS   = ['%s',        '%s',  '%0.2f',           '%0.2f',              '%s'             ]
    NODE_LABELS   = ['Node',      'PID', 'CPU %',           'Mem %',              'Num Threads'    ]
    SORT_TYPE     = [str,         str,   float,             float,                float            ]
    TOOLTIPS      = {
        0: ('cmdline', lambda x: '\n'.join(textwrap.wrap(' '.join(x)))),
        3: ('memory_info', lambda x: ('Resident: %0.2f MiB, Virtual: %0.2f MiB' % (x[0]/2**20, x[1]/2**20)))
    }

    _node_info = NodeInfo()

    name_filter = re.compile('')

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

        # 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

        self._selected_node = ''
        self._selected_node_lock = RLock()

        # Setup the toolbar
        self._toolbar = QToolBar()
        self._filter_box = QLineEdit()
        self._regex_box  = QCheckBox()
        self._regex_box.setText('regex')
        self._toolbar.addWidget(QLabel('Filter'))
        self._toolbar.addWidget(self._filter_box)
        self._toolbar.addWidget(self._regex_box)

        self._filter_box.returnPressed.connect(self.update_filter)
        self._regex_box.stateChanged.connect(self.update_filter)

        # Create a container widget and give it a layout
        self._container = QWidget()
        self._container.setWindowTitle('Process Monitor')
        self._layout    = QVBoxLayout()
        self._container.setLayout(self._layout)

        self._layout.addWidget(self._toolbar)

        # Create the table widget
        self._table_widget = QTreeWidget()
        self._table_widget.setObjectName('TopTable')
        self._table_widget.setColumnCount(len(self.NODE_LABELS))
        self._table_widget.setHeaderLabels(self.NODE_LABELS)
        self._table_widget.itemClicked.connect(self._tableItemClicked)
        self._table_widget.setSortingEnabled(True)
        self._table_widget.setAlternatingRowColors(True)

        self._layout.addWidget(self._table_widget)
        context.add_widget(self._container)

        # Add a button for killing nodes
        self._kill_button = QPushButton('Kill Node')
        self._layout.addWidget(self._kill_button)
        self._kill_button.clicked.connect(self._kill_node)

        # Update twice since the first cpu% lookup will always return 0
        self.update_table()
        self.update_table()

        self._table_widget.resizeColumnToContents(0)

        # Start a timer to trigger updates
        self._update_timer = QTimer()
        self._update_timer.setInterval(1000)
        self._update_timer.timeout.connect(self.update_table)
        self._update_timer.start()

    def _tableItemClicked(self, item, column):
        with self._selected_node_lock:
            self._selected_node = item.text(0)

    def update_filter(self, *args):
        if self._regex_box.isChecked():
            expr = self._filter_box.text()
        else:
            expr = re.escape(self._filter_box.text())
        self.name_filter = re.compile(expr)
        self.update_table()

    def _kill_node(self):
        self._node_info.kill_node(self._selected_node)

    def update_one_item(self, row, info):
        twi = TopWidgetItem()
        for col, field in enumerate(self.OUT_FIELDS):
            val = info[field]
            twi.setText(col, self.FORMAT_STRS[col] % val)
        self._table_widget.insertTopLevelItem(row, twi)

        for col, (key, func) in self.TOOLTIPS.items():
            twi.setToolTip(col, func(info[key]))

        with self._selected_node_lock:
            if twi.text(0) == self._selected_node:
                twi.setSelected(True)

        twi.setHidden(len(self.name_filter.findall(info['node_name'])) == 0)

    def update_table(self):
        self._table_widget.clear()
        infos = self._node_info.get_all_node_fields(self.NODE_FIELDS)
        for nx, info in enumerate(infos):
            self.update_one_item(nx, info)

    def shutdown_plugin(self):
        self._update_timer.stop()

    def save_settings(self, plugin_settings, instance_settings):        
        instance_settings.set_value('filter_text', self._filter_box.text())
        instance_settings.set_value('is_regex', int(self._regex_box.checkState()))

    def restore_settings(self, plugin_settings, instance_settings):
        self._filter_box.setText(instance_settings.value('filter_text'))
        is_regex_int = instance_settings.value('is_regex')
        if is_regex_int:
            self._regex_box.setCheckState(Qt.CheckState(is_regex_int))
        else:
            self._regex_box.setCheckState(Qt.CheckState(0))
        self.update_filter()