26 from __future__
import division
31 from python_qt_binding
import loadUi
32 from python_qt_binding.QtCore
import Qt, QTimer, Signal, Slot, QRectF
33 from python_qt_binding.QtWidgets
import QWidget, QVBoxLayout, QLabel, QPushButton, QHBoxLayout,\
34 QScrollArea, QGraphicsScene
35 from python_qt_binding.QtGui
import QPixmap
39 from rospy.exceptions
import ROSException
41 from .topic_info
import TopicInfo
42 from .subsystem_widget
import SubsystemWidget
46 main class inherits from the ui window class. 48 You can specify the topics that the topic pane. 50 SystemWidget.start must be called in order to update topic pane. 53 _column_names = [
'topic',
'type',
'bandwidth',
'rate',
'value']
61 ui_file = os.path.join(rp.get_path(
'rqt_agent'),
'resource',
'SystemWidget.ui')
83 self.graphicsView.setScene(QGraphicsScene(0,0,10,10))
93 if not subsystem_name
in self.
_widgets:
104 for subsystem_name
in self.
_widgets:
111 This method needs to be called to start updating topic pane. 116 return (layout.itemAt(i)
for i
in range(layout.count()))
121 refresh tree view items 126 topic_list = rospy.get_published_topics()
127 if topic_list
is None:
128 rospy.logerr(
'Not even a single published topic found. Check network configuration')
134 for topic_name, topic_type
in topic_list:
135 name_split = topic_name.split(
'/')
137 if (len(name_split) == 3)
and (name_split[0] ==
'')
and (name_split[2] ==
'diag')
and (topic_type ==
"diagnostic_msgs/DiagnosticArray"):
138 subsystem_name = name_split[1]
142 topic_info =
TopicInfo(topic_name, topic_type)
143 new_subsystems[subsystem_name] = topic_info
144 topic_info.start_monitoring()
148 new_subsystems[subsystem_name] = self.
_subsystems[subsystem_name]
155 if not s
in new_subsystems:
170 msg = self.
_subsystems[subsystem_name].last_message
172 if (msg !=
None)
and (len(msg.status) == 2)
and \
173 msg.status[0].name ==
'components' and msg.status[1].name ==
'diagnostics':
174 name_split = subsystem_name.split(
'/')
179 if not subsystem_name
in self.
_widgets:
182 new_widgets[subsystem_name] = self.
_widgets[subsystem_name]
187 if structure_changed:
191 allInitialized =
True 192 for subsystem_name, wg
in new_widgets.iteritems():
193 if not wg.isInitialized():
194 allInitialized =
False 204 for it
in range(100):
205 if self.verticalLayout.isEmpty():
207 self.verticalLayout.removeWidget()
208 self.verticalLayout.takeAt(0)
209 print 'removed widget', it
212 for subsystem_name, wg
in self.
_widgets.iteritems():
215 for wg_name, wg
in self.
_widgets.iteritems():
216 self.verticalLayout.addWidget(wg)
218 print 'added widget', wg_name
232 for subsystem_name
in self.
_widgets:
233 self.
_widgets[subsystem_name].update_subsystem(self.
_subsystems[subsystem_name].last_message)
236 dot =
'digraph system {\n' 237 all_buf_names = set()
238 for subsystem_name, wg
in self.
_widgets.iteritems():
239 if not wg.isInitialized():
240 dot +=
' {} [style="filled,rounded" fillcolor=orange shape=box];\n'.format(subsystem_name)
243 dot +=
' {} [style=rounded shape=box];\n'.format(subsystem_name)
245 for buf_name
in wg.subsystem_info.upper_inputs:
246 dot +=
' {} -> {};\n'.format(buf_name, subsystem_name)
247 all_buf_names.add(buf_name)
249 for buf_name
in wg.subsystem_info.lower_inputs:
250 dot +=
' {} -> {} [arrowhead=none arrowtail=normal dir=back];\n'.format(subsystem_name, buf_name)
251 all_buf_names.add(buf_name)
253 for buf_name
in wg.subsystem_info.upper_outputs:
254 dot +=
' {} -> {} [arrowhead=none arrowtail=normal dir=back];\n'.format(buf_name, subsystem_name)
255 all_buf_names.add(buf_name)
257 for buf_name
in wg.subsystem_info.lower_outputs:
258 dot +=
' {} -> {};\n'.format(subsystem_name, buf_name)
259 all_buf_names.add(buf_name)
261 for buf_name
in all_buf_names:
262 dot +=
' {} [shape=box];\n'.format(buf_name)
265 tmpdirname = tempfile.mkdtemp()
266 in_read, in_write = os.pipe()
267 os.write(in_write, dot)
269 subprocess.call([
'dot',
'-Tpng',
'-o{}/system.png'.format(tmpdirname)], stdin=in_read)
273 self.graphicsView.scene().clear()
274 self.graphicsView.scene().update()
275 pixmap = QPixmap(
'{}/system.png'.format(tmpdirname))
276 self.graphicsView.scene().addPixmap(pixmap)
277 self.graphicsView.scene().setSceneRect(QRectF(pixmap.rect()))
278 os.remove(
'{}/system.png'.format(tmpdirname))
282 for topic
in self._topics.values():
283 topic[
'info'].stop_monitoring()
288 @param selected_topics: list of tuple. [(topic_name, topic_type)] 289 @type selected_topics: [] 291 rospy.logdebug(
'set_selected_topics topics={}'.format(
292 len(selected_topics)))
297 header_state = self.topics_tree_widget.header().saveState()
298 instance_settings.set_value(
'tree_widget_header_state', header_state)
301 if instance_settings.contains(
'tree_widget_header_state'):
302 header_state = instance_settings.value(
'tree_widget_header_state')
303 if not self.topics_tree_widget.header().restoreState(header_state):
304 rospy.logwarn(
"rqt_topic: Failed to restore header state.")