Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Machinery for re-configurable snapshot streams #28

Merged
merged 9 commits into from
Dec 26, 2019
2 changes: 2 additions & 0 deletions .settings/org.eclipse.core.resources.prefs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
eclipse.preferences.version=1
encoding//py_trees_ros_viewer/backend.py=utf-8
encoding//py_trees_ros_viewer/conversions.py=utf-8
encoding//py_trees_ros_viewer/exceptions.py=utf-8
encoding//py_trees_ros_viewer/main_window.py=utf-8
encoding//py_trees_ros_viewer/utilities.py=utf-8
encoding//py_trees_ros_viewer/viewer.py=utf-8
encoding//py_trees_ros_viewer/web_view.py=utf-8
encoding//py_trees_ros_viewer/web_view_ui.py=utf-8
348 changes: 313 additions & 35 deletions py_trees_ros_viewer/backend.py

Large diffs are not rendered by default.

33 changes: 33 additions & 0 deletions py_trees_ros_viewer/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# License: BSD
# https://raw.githubusercontent.com/splintered-reality/py_trees_ros/devel/LICENSE
#
##############################################################################
# Documentation
##############################################################################

"""
Custom exception types for py_trees_ros_viewer.
"""

##############################################################################
# Imports
##############################################################################


class NotReadyError(Exception):
"""
Typically used when methods have been called that expect, but have not
pre-engaged in the ROS2 specific setup typical of py_trees_ros classes
and behaviours.
"""
pass


class TimedOutError(Exception):
"""
Timed out waiting (typically) for middleware connections to be established.
"""
pass
41 changes: 22 additions & 19 deletions py_trees_ros_viewer/html/index.html
Original file line number Diff line number Diff line change
@@ -1,31 +1,34 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>PyTrees Viewer</title>
<link rel="stylesheet" href="js/py_trees-0.5.1.css">
<link rel="stylesheet" type="text/css" href="js/jointjs/joint-3.0.4.min.css"/>
<script src="js/jointjs/dagre-0.8.4.min.js"></script>
<script src="js/jointjs/graphlib-2.1.7.min.js"></script>
<script src="js/jointjs/jquery-3.4.1.min.js"></script>
<script src="js/jointjs/lodash-4.17.11.min.js"></script>
<script src="js/jointjs/backbone-1.4.0.js"></script>
<script src="js/jointjs/joint-3.0.4.min.js"></script>
<script src="js/py_trees-0.5.1.js"></script>
<style>
html {
height: 100% /* for the canvas to fill the screen, need heights cascaded from the top */
}
body {
margin: 0;
overflow:hidden; /* no scrollbars */
height: 100% /* for the canvas to fill the screen, need heights cascaded from the top */
}
</style>
</head>
<script src="js/jointjs/dagre-0.8.4.min.js"></script>
<script src="js/jointjs/graphlib-2.1.7.min.js"></script>
<script src="js/jointjs/jquery-3.4.1.min.js"></script>
<script src="js/jointjs/lodash-4.17.11.min.js"></script>
<script src="js/jointjs/backbone-1.4.0.js"></script>
<script src="js/jointjs/joint-3.0.4.min.js"></script>
<script src="js/py_trees-0.5.1.js"></script>
<link rel="stylesheet" href="js/py_trees-0.5.1.css">
<link rel="stylesheet" type="text/css" href="js/jointjs/joint-3.0.4.min.css"/>
<style>
body {
margin: 0;
overflow:hidden;
}
</style>
<body>
<script type="text/javascript">
py_trees.hello()
</script>
<div id="window">
<div id="canvas"></div>
<div id="timeline"></div>
</div>
<div id="canvas"></div>
<div id="timeline"></div>
<script type="text/javascript">
// rendering canvas
canvas_graph = py_trees.canvas.create_graph()
Expand Down
54 changes: 40 additions & 14 deletions py_trees_ros_viewer/main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
# Imports
##############################################################################

import json

import PyQt5.QtCore as qt_core
import PyQt5.QtWidgets as qt_widgets

Expand Down Expand Up @@ -58,43 +56,50 @@ def on_tree_rendered(self, response):
console.logdebug("response from js/render_tree ['{}'][window]".format(response))

@qt_core.pyqtSlot(list)
def on_discovered_topics_changed(self, discovered_topics):
console.logdebug("discovered topics changed callback {}[window]".format(discovered_topics))
def on_discovered_namespaces_changed(self, discovered_namespaces):
console.logdebug("discovered namespaces changed callback {}[window]".format(discovered_namespaces))
if (discovered_namespaces):
self.ui.send_button.setEnabled(False)
else:
self.ui.send_button.setEnabled(True)

discovered_topics.sort()
discovered_namespaces.sort()

current_selection = self.ui.topic_combo_box.currentText()
if current_selection:
console.logdebug("currently selected topic: {}".format(current_selection))
console.logdebug("currently selected namespace: {}".format(current_selection))
else:
console.logdebug("currently selected topic: none")
console.logdebug("currently selected namespace: none")

# if current_selection and current_selection not in discovered_topics:
# discovered_topics.append(current_selection)

for topic in discovered_topics:
if self.ui.topic_combo_box.findText(topic) < 0:
self.ui.topic_combo_box.addItem(topic)
for namespace in discovered_namespaces:
if self.ui.topic_combo_box.findText(namespace) < 0:
self.ui.topic_combo_box.addItem(namespace)
for index in range(self.ui.topic_combo_box.count()):
topic = self.ui.topic_combo_box.itemText(index)
if topic != current_selection:
if topic not in discovered_topics:
if topic not in discovered_namespaces:
self.ui.topic_combo_box.removeItem(index)

if current_selection:
self.ui.topic_combo_box.setCurrentText(current_selection)
else:
self.ui.topic_combo_box.setCurrentIndex(0)
# can't seem to get at the str version of this, always requires the int
# self.ui.topic_combo_box.activated.emit(discovered_topics[0])
# self.topic_selected_automagically.emit(discovered_topics[0])
# self.ui.topic_combo_box.activated.emit(discovered_namespaces[0])
# self.topic_selected_automagically.emit(discovered_namespaces[0])

@qt_core.pyqtSlot()
def onLoadFinished(self):
console.logdebug("web page loaded [window]")
self.web_app_loaded = True
self.ui.send_button.setEnabled(True)
self.ui.send_button.setEnabled((self.ui.topic_combo_box.currentIndex() == -1))
self.ui.screenshot_button.setEnabled(True)
self.ui.blackboard_activity_checkbox.setEnabled(True)
self.ui.blackboard_data_checkbox.setEnabled(True)
self.ui.periodic_checkbox.setEnabled(True)
if self.pre_loaded_tree:
javascript_command = "render_tree({{tree: {}}})".format(self.pre_loaded_tree)
web_view_page = self.ui.web_view_group_box.ui.web_engine_view.page()
Expand All @@ -115,9 +120,30 @@ def readSettings(self):
window_state = settings.value("window_state") # full size, maximised, minimised, no state
if window_state is not None:
self.restoreState(window_state)
self.ui.blackboard_data_checkbox.setChecked(
settings.value("blackboard_data", defaultValue=True, type=bool)
)
self.ui.blackboard_activity_checkbox.setChecked(
settings.value("blackboard_activity", defaultValue=False, type=bool)
)
self.ui.periodic_checkbox.setChecked(
settings.value("periodic", defaultValue=True, type=bool)
)

def writeSettings(self):
console.logdebug("write settings [window]")
settings = qt_core.QSettings("Splintered Reality", "PyTrees Viewer")
settings.setValue("geometry", self.saveGeometry())
settings.setValue("window_state", self.saveState()) # full size, maximised, minimised, no state
settings.setValue(
"blackboard_data",
self.ui.blackboard_data_checkbox.isChecked()
)
settings.setValue(
"blackboard_activity",
self.ui.blackboard_activity_checkbox.isChecked()
)
settings.setValue(
"periodic",
self.ui.periodic_checkbox.isChecked()
)
59 changes: 49 additions & 10 deletions py_trees_ros_viewer/main_window.ui
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>799</width>
<height>356</height>
<width>1051</width>
<height>567</height>
</rect>
</property>
<property name="windowTitle">
Expand All @@ -18,7 +18,7 @@
<normaloff>:/images/tuxrobot.png</normaloff>:/images/tuxrobot.png</iconset>
</property>
<widget class="QWidget" name="central_display">
<layout class="QVBoxLayout" name="verticalLayout_4">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="tools_frame">
<property name="sizePolicy">
Expand All @@ -37,7 +37,7 @@
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Topic</string>
<string>Namespace</string>
</property>
</widget>
</item>
Expand All @@ -51,6 +51,16 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="send_button">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Send Demo Tree</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
Expand All @@ -65,22 +75,51 @@
</spacer>
</item>
<item>
<widget class="QPushButton" name="screenshot_button">
<widget class="QCheckBox" name="blackboard_data_checkbox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Screenshot</string>
<string>Blackboard Data</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="send_button">
<widget class="QCheckBox" name="blackboard_activity_checkbox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Send Demo Tree</string>
<string>Blackboard Activity</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="periodic_checkbox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Periodic</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="screenshot_button">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Screenshot</string>
</property>
</widget>
</item>
Expand All @@ -107,8 +146,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>799</width>
<height>35</height>
<width>1051</width>
<height>29</height>
</rect>
</property>
<property name="defaultUp">
Expand Down
42 changes: 30 additions & 12 deletions py_trees_ros_viewer/main_window_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(799, 356)
MainWindow.resize(1051, 567)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/images/tuxrobot.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
MainWindow.setWindowIcon(icon)
self.central_display = QtWidgets.QWidget(MainWindow)
self.central_display.setObjectName("central_display")
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.central_display)
self.verticalLayout_4.setObjectName("verticalLayout_4")
self.verticalLayout = QtWidgets.QVBoxLayout(self.central_display)
self.verticalLayout.setObjectName("verticalLayout")
self.tools_frame = QtWidgets.QFrame(self.central_display)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
Expand All @@ -38,17 +38,32 @@ def setupUi(self, MainWindow):
self.topic_combo_box.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToContents)
self.topic_combo_box.setObjectName("topic_combo_box")
self.horizontalLayout.addWidget(self.topic_combo_box)
self.send_button = QtWidgets.QPushButton(self.tools_frame)
self.send_button.setEnabled(False)
self.send_button.setObjectName("send_button")
self.horizontalLayout.addWidget(self.send_button)
spacerItem = QtWidgets.QSpacerItem(186, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem)
self.blackboard_data_checkbox = QtWidgets.QCheckBox(self.tools_frame)
self.blackboard_data_checkbox.setEnabled(False)
self.blackboard_data_checkbox.setChecked(True)
self.blackboard_data_checkbox.setObjectName("blackboard_data_checkbox")
self.horizontalLayout.addWidget(self.blackboard_data_checkbox)
self.blackboard_activity_checkbox = QtWidgets.QCheckBox(self.tools_frame)
self.blackboard_activity_checkbox.setEnabled(False)
self.blackboard_activity_checkbox.setChecked(False)
self.blackboard_activity_checkbox.setObjectName("blackboard_activity_checkbox")
self.horizontalLayout.addWidget(self.blackboard_activity_checkbox)
self.periodic_checkbox = QtWidgets.QCheckBox(self.tools_frame)
self.periodic_checkbox.setEnabled(False)
self.periodic_checkbox.setChecked(True)
self.periodic_checkbox.setObjectName("periodic_checkbox")
self.horizontalLayout.addWidget(self.periodic_checkbox)
self.screenshot_button = QtWidgets.QPushButton(self.tools_frame)
self.screenshot_button.setEnabled(False)
self.screenshot_button.setObjectName("screenshot_button")
self.horizontalLayout.addWidget(self.screenshot_button)
self.send_button = QtWidgets.QPushButton(self.tools_frame)
self.send_button.setEnabled(False)
self.send_button.setObjectName("send_button")
self.horizontalLayout.addWidget(self.send_button)
self.verticalLayout_4.addWidget(self.tools_frame)
self.verticalLayout.addWidget(self.tools_frame)
self.web_view_group_box = WebViewGroupBox(self.central_display)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
Expand All @@ -57,10 +72,10 @@ def setupUi(self, MainWindow):
self.web_view_group_box.setSizePolicy(sizePolicy)
self.web_view_group_box.setTitle("")
self.web_view_group_box.setObjectName("web_view_group_box")
self.verticalLayout_4.addWidget(self.web_view_group_box)
self.verticalLayout.addWidget(self.web_view_group_box)
MainWindow.setCentralWidget(self.central_display)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 799, 35))
self.menubar.setGeometry(QtCore.QRect(0, 0, 1051, 29))
self.menubar.setDefaultUp(False)
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
Expand All @@ -74,9 +89,12 @@ def setupUi(self, MainWindow):
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "PyTrees Viewer"))
self.label.setText(_translate("MainWindow", "Topic"))
self.screenshot_button.setText(_translate("MainWindow", "Screenshot"))
self.label.setText(_translate("MainWindow", "Namespace"))
self.send_button.setText(_translate("MainWindow", "Send Demo Tree"))
self.blackboard_data_checkbox.setText(_translate("MainWindow", "Blackboard Data"))
self.blackboard_activity_checkbox.setText(_translate("MainWindow", "Blackboard Activity"))
self.periodic_checkbox.setText(_translate("MainWindow", "Periodic"))
self.screenshot_button.setText(_translate("MainWindow", "Screenshot"))

from py_trees_ros_viewer.web_view import WebViewGroupBox
from . import images_rc
Loading