Embedded Multitouch (HMI 2014)

646 Aufrufe

Veröffentlicht am

Aus dem Projektalltag: Embedded Multitouch mit QML/QtQuick 2

Veröffentlicht in: Software
0 Kommentare
0 Gefällt mir
Statistik
Notizen
  • Als Erste(r) kommentieren

  • Gehören Sie zu den Ersten, denen das gefällt!

Keine Downloads
Aufrufe
Aufrufe insgesamt
646
Auf SlideShare
0
Aus Einbettungen
0
Anzahl an Einbettungen
5
Aktionen
Geteilt
0
Downloads
2
Kommentare
0
Gefällt mir
0
Einbettungen 0
Keine Einbettungen

Keine Notizen für die Folie

Embedded Multitouch (HMI 2014)

  1. 1. • Texas Instruments Sitara SoC • CPU: ARM Cortex-A8, 600 MHz, Single Core • GPU: Imagination Technologies PowerVR SGX 530 • 256 MB RAM • 512 MB Flash • Display • kapazitiv, Multitouch • 7 Zoll, 800x480 px Jahn Fuchs, Zühlke Engineering GmbH | Aus dem Projektalltag: Embedded Multitouch mit QML/QtQuick 2 1 Aus dem Projektalltag: Embedded Multitouch mit QML/QtQuick 2 Ziel dieses Vortrags ist es dem Zuhörer einen Überblick über QtQuick 2/QML anhand eines (bereits umgesetzten) Projektes zu verschaffen und ein Gefühl vermitteln, ob diese Technologie für eigene Projekte interessant ist und mit welchen Herausforderungen zu rechnen ist. Ein Premiumhersteller für Präzisions- Lasersysteme für Wissenschaft und Industrie möchte im Rahmen einer Produkt-neuentwicklung ein Multitouch-Display einsetzen. Wir werden wichtige Heraus-forderungen und Erkenntnisse dieses inzwischen umgesetzten Projekts herausgreifen und betrachten. Umgesetzt wurde das Projekt mit Qt Quick 2, einer Technologie, die mit solidem C++ Backend direkt auf OpenGL aufbaut, dabei aber das Erstellen von Oberflächen in der deklarativen Sprache QML mit hoher Abstraktion erlaubt. Gegenstand des Entwickungsprojekts war ein digitaler Laser-Controller. Im Vergleich zu bisherigen Modellen sollte die neue Produktgeneration mit Touch bedienbar sein und mehr Komfort bieten. Abbildung 1: Laser-Controller vorheriger Generation Neben der technischen Umsetzung war die Gestaltung eines stimmigen Gesamtdesigns der Frontplatte und der Benutzeroberfläche ebenso Gegenstand dieses Projektes. Abbildung 2: Diodenlaser-System, bestehend aus dem Laser-Kopf mit der Laser-Diode (die blaue Box) und dem Laser-Controller mit Touch-Display (das weiße Rack mit den roten Griffen) In diesem Vortrag werde ich auf wichtige technische Details der Implementierung und der Architektur, die auf Embedded Linux, C++ und QtQuick2/QML aufsetzt, eingehen. Außerdem werde ich auf die Performance bei Multitouch im embedded Bereich eingehen, so wie auf das Zusammenspiel des Multitouch-Displays mit anderen Eingabeformen. Zum Schluss machen wir noch einen kurzen Ausflug in das Thema automatisiertes Testen von QML Anwendungen. Hardware Fundament Die Hardware wurde in diesem Projekt schon vom Kunden vor unserem Eintritt in das Projekt ausgewählt. Im Vergleich zu heutigen Smartphones mit 4-Kern-Prozessoren bewegt sich die Hardware leistungsmäßig eher in der unteren Klasse. Jedoch verfügt die Hardware schon über eine GPU, die eine grafische Beschleunigung der Oberfläche mittels OpenGL ermöglicht. Abbildung 3: Hardware-Fundament des Laser-Controllers
  2. 2. Jahn Fuchs, Zühlke Engineering GmbH | Aus dem Projektalltag: Embedded Multitouch mit QML/QtQuick 2 2 In diesem Projekt existiert nur eine Vollbild- Benutzeroberfläche, die auf den Bildschirm zugreift. Der Prozess der Benutzeroberfläche teilt sich den Einkern-Prozessor mit dem Hauptsteuerprozess und kleineren Service- Skripten. QtDeclarative-Architektur Im Abbildung 4 ist der Software-Stack von Qt Quick bildlich dargestellt. Der Titel QtDeclarative-Architektur bewusst gewählt, da Qt Quick und QML selbst nur Teile des gesamten Systems sind. Die entsprechenden Quellen findet man bei Qt im QtDeclarative Modul. Abbildung 4: QtDeclarative-Architektur Von der unten startend: • Die unterste Schicht (lila) stellt die zugrundeliegende Hardware dar. Neben der CPU ist auch die GPU ein wichtiges Element. Qt Quick 2 benötigt OpenGL und baut auf Hardwarebeschleunigung. • Der Betriebssystem-Kern (blau) abstrahiert die Hardware, z.B. mittels eines OpenGL-Treibers. In unserem Fall kommt der OpenGL-Treiber als quelloffenes Linux-Kernel-Modul vom Hersteller des SoC, dem „TI Graphics SDK“. • Die eigentliche OpenGL-API-Implementierung liegt als Userspace- Library vor und ist nicht quelloffen. Sie ist ebenfalls Bestandteil des TI Graphics SDK. • Die in grün dargestellten Blöcke (QtDeclarative Frontend, Scenegraph Backend, QtQuick Items) werden von Qt bereitgestellt. Direkt auf dem Betriebssystem setzt das QtBase-Modul auf. Das QtDeclarative-Modul stellt die QML und Javascript-Engines zur Verfügung. • Das Scenegraph-Backend ist als eigener Block dargestellt, da es von der QML-Welt einigermaßen deutlich getrennt ist. Der Scenegraph nutzt ein sog. Platform Plugin, das die Anbindung an den nativen Fenster-Manager – oder allgemeiner: den Grafik-Kontext – vornimmt. Hier passiert die Anbindung an den Fenster-Manager bei Desktop-Systemen, also bei Linux z.B. X11 oder Wayland. Für Embedded Systeme ohne Fenster-Manager – also Anwendungen mit nur einem GUI-Prozess – ist das EGLFS-Plugin gut geeignet. EGLFS = EGL (OpenGL-API) Fullscreen. In den EGLFS Hooks können Anpassungen an die jeweilige Hardware vorgenommen werden (z.B. LCD Refresh Rate). Auf den Scenegraph werden wir im Detail in den nächsten Abschnitten eingehen. • Ganz oben steht die eigentliche Anwendung, die typischerweise sowohl aus Standard-Items sowie Anwendungs-spezifischen Items (Custom Items) besteht. Auf Custom Items werden wir im späteren Verlauf noch ausführlicher eingehen.
  3. 3. Jahn Fuchs, Zühlke Engineering GmbH | Aus dem Projektalltag: Embedded Multitouch mit QML/QtQuick 2 3 Kurzer QML Überblick QML ist die deklarative, zur Laufzeit interpretierte, Sprache mit der sich in Qt Quick Oberflächen beschreiben lassen. QML kann mit Javascript angereichert werden, z.B. für Interface-Logik auf hoher Ebene. Durch QML ist eine gute Aufteilung von Arbeiten zwischen Interface Designer und Programmierer möglich. Das solide Backend ermöglicht es performance-kritische Teile in C++ zu schreiben. QML kommt mit vielen Funktionalitäten „out of the Box“ wie z.B. Animationen, States und Transitionen, OpenGL Shader und Multitouch Support. QML im Detail zu besprechen liegt außerhalb des Rahmens dieses Vortrags. Für den Interessierten findet sich im Internet eine Fülle von Tutorials und Einführungen. Custom QML Items QML kommt in QtQuick mit vielen Funktionalitäten von Haus aus und in den neuesten Versionen finden sich sogar Kontrollelemente wie Slider oder Fortschrittsbalken. Auch lassen sich in QML selber wiederverwendbare Komponenten schreiben. Bei nicht-trivialen Anwendungen stößt man auch damit jedoch schnell an die Grenzen des machbaren. Als Beispiel nehmen wir das Plot-Anzeige- und Kontrollelement aus der Laser-Controller Oberfläche (Abbildung 5). Dieses Element soll verschiedene Messkurven des Lasers anzeigen. Dem Nutzer soll es möglich sein die Anzeige mit Pan- und Zoomgesten zu ändern. Hierbei werden transparent im Hintergrund neue Laserparameter gesetzt und neue Messwerte angefordert. Abbildung 5: Foto der Laser-Controller Benutzeroberfläche Dies lässt sich sogar rein in QML und Javascript lösen (es existiert ein QML Canvas Item auf dem sich mit Javascript malen lässt). Dies ist jedoch nicht sehr performant – der Nutzer erwartet ein fluides Verhalten bei den Gesten, wie er es von seinem Smartphone kennt. Qt bietet hier die Möglichkeit eigene visuelle Items in C++ zu implementieren. Möchte man „Custom QML Items“ implementieren dann benötigt man jedoch auf jeden Fall ein Grundverständnis des QtQuick Scene Graphs und dessen API. Seit QtQuick 2 läuft alles Rendering über den Scene Graph. Bei komplexen Items oder Items mit besonderen Perfomance-Anforderungen ist außerdem OpenGL KnowHow empfehlenswert. Die Scene Graph API ist in großen Teilen eine Abstrahierung der OpenGL API, aber dennoch sehr nahe an OpenGL dran. Entwicklern die sich schon mit OpenGL beschäftigt haben, werden viele Funktionen und Methoden bekannt vorkommen.
  4. 4. Jahn Fuchs, Zühlke Engineering GmbH | Aus dem Projektalltag: Embedded Multitouch mit QML/QtQuick 2 4 Der Scene Graph Der Scene Graph ist zentraler Bestandteil des QtDeclarative Moduls. Es wird über den Scene Graph mit OpenGL gerendert und dargestellt. Abbildung 6: Qt/QML Architektur vor und nach Einführung des Scene Graphs Der Scene Graph wurde aus Performance- Gründen eingeführt. Abbildung 6 zeigt auf hoher Abstraktions-ebene wie sich der Scene Graph auf die Architektur im Vergleich zu QtQuick1 auswirkt. Der Scene Graph ist die graphische Repräsentation der QML Szene, also aller visuellen QML Items. In Abbildung 7 sehen wir eine beispielhafte Darstellung eines Scene Graphs. Abbildung 7: Der Scene Graph enthält die grafische Repräsentation der aller QML Items der QML Szene auf dem Bildschirm. Der Scene Graph ist eine Baumstruktur, die aus einzelnen QSG-Knoten (QtSceneGraph Nodes) aufgebaut ist. Wir werden später noch darauf eingehen, wann der Scene Graph mit der QML Szene abgeglichen wird. Ein Vorteil von der Benutzung einen Scene Graphs im Vergleich zu anderen (imperativen) Systemen (wie z.B. QPainter) ist, dass die zu renderne Szene zwischen den einzelnen Frames erhalten bleibt und vor dem eigentlichen Rendern, der komplette Satz von Primitiven bekannt ist. Das Scene Graph Renderer optmiert, indem er versucht die Anzahl der OpenGL Aufrufe zu minimieren. Dies passiert z.B. durch Batching (zusammenfassen von gleichartigen Primitiven) oder Sortieren nach Objekten mit und ohne Transparenz. Der Scene Graph Renderer wendet auch weitere Optmierungen an wie z.B. das packen von kleinen Texturen in eine große (Texture Atlas) und versucht unveränderte Bildschirmbereiche zu detektieren. Ohne zu sehr auf C++ Implementierungs-details einzugehen möchte ich im Folgenden noch kurz ausführen wie Custom QML Items in QtQuick realisiert werden. QQuickItem Um ein Custom QML Item zu implementieren leitet man von der Basisklasse aller visuellen QML Items „QQuickItem“ ab und implementiert, die updatePaintNode Methode. In dieser Methode besteht die Möglichkeit einen Unterknoten bzw. Unterbaum aus dem Scene Graph zu erstellen, manipulieren, zu löschen oder einfach im aktuellen Zustand belassen. Abbildung 8: Der Scene Graph Renderer aktualisiert den Scene Graph in dem die updatePaintNode Methode der QML Items aufgerufen wird. Wenn der Scene Graph aktualisiert wird werden die virtuelle updatePaintNode Methode aller visuellen QML Items aufgerufen.
  5. 5. Jahn Fuchs, Zühlke Engineering GmbH | Aus dem Projektalltag: Embedded Multitouch mit QML/QtQuick 2 5 Für Legacy Code: QQuickPaintedItem QQuickPaintedItem ermöglicht die Verwendung von der QPainter API für die Implementierung von Custom QML Items im Zusammenspiel mit dem Scene Graph. Dies kann sinnvoll für Legacy Code sein oder für einfache Items und Programmen bei denen Performance keine Rollen spielen. Abbildung 9: QQuickPaintedItem Standardverhalten: Es wird in ein Image gemalt, dies wir d als Textur verwendet. Beim Standardverhalten des QQuickPaintedItem wird in ein Bild mit der QPainter API gemalt, welches dann als Textur verwendet wird. QQuickpaintedItem bietet auch die Option direkt mit der OpenGL PaintEngine in ein Framebufferobjekt zu zeichnen. Beide Varianten bringen jedoch immer Perfomance-Einbußen mit sich. Das Verhalten ist dann dem in Abbildung 6 links Vergleichbar. QtQuick Rendering Insbesondere von Touch-Benutzeroberflächen erwartet der Benutzer heute flüssige Bedienung und flüssige Animationen. Selbst bei einer sehr einfachen und technischen Oberfläche, wie z.B. bei den Parametermenüs des Laser-Controllers kommen durch Bedienelemente wie z.B. scrollbaren Listen automatisch neue Anforderungen hinzu. Die Liste muss beim scrollen flüssig animiert sein. Ein Bildschirm hat üblicherweise eine Bildwiederholrate von 60Hz, dies bedeutet im Umkehrschluss, dass für wirklich flüssige Animationen jede 16ms ein neues Bild erzeugt und angezeigt werden muss. Abbildung 10: Durch Elemente wie z.B. scrollbare Listen in einer Oberfläche bringen implizite Anforderungen an die Performance mit sich. Werden zu viele Bilder nicht rechtzeitig auf dem Bildschirm aktualisiert wird dies als ruckeln wahrgenommen. Man kann sich heute quasi keine grafische Touch-Oberfläche ohne flüssig animierte Elemente vorstellen. Provokant gefragt: Bedeuted Multitouch = Echtzeit? QtQuick verwendet zwei Threads: den GUI Thread und den Render Thread. Im GUI Thread wird die QML Szene berechnet (z.B. die Schritte von einer animierten Transition von einem State in den nächsten) und die Applikation hat Zeit sich anderen Dingen zuzuwenden. Abbildung 11: QtQuick Rendering Der GUI Thread teilt mit, wenn der die QML Szene mit dem Scene Graph synchronisiert werden kann. Mit dem VSync-Signal werden
  6. 6. Jahn Fuchs, Zühlke Engineering GmbH | Aus dem Projektalltag: Embedded Multitouch mit QML/QtQuick 2 6 darauf hin die Framebuffer getauscht und der Scene Graph akualisiert. Während der Synchronisation ist der GUI Thread blockiert. Dann können wieder beide Threads parallel arbeiten. Wenn es ruckelt Sollte es ruckeln und zu Performance-problemen kommen kann man der Ursache mit Profiling auf den Grund gehen. Hier bietet QtQuick verschiedene Optionen an (z.B. QSG_RENDER_TIMING oder QST_RENDERER_DEBUG) mit denen Details zu den einzelnen Renderschritten ausgegeben werden. Man sollte unbedingt darauf achten die Komplexität der QML-Szene reduzieren. Wenn man auf transparente Objekte (z.B. PNG Bilder) verzichten kann, bringt dies auch einen Performancevorteil. Sollten Profiling und Komplexitätsreduzierung der QML Szene nicht zum Erfolg führen gibt es auch noch die Möglichkeit das Scene Graph Backend im Ganzen oder in Teilen für die eigene Applikation zu optimieren oder gar ganz auszutauschen. Weitere Hinweise für Performance-Tuning finden sich auf dem Blog von Gunnar Sletta: http://blog.qt.digia.com/blog/author/gunnar Testen von QML Anwendungen Obwohl die Wichtigkeit von Softwaretests bekannt ist, werden Tests doch sehr oft vernachlässigt. Bei QML Anwendungen sind Tests nicht minder wichtig. QML ist eine deklarative Spache, die zur Laufzeit interpretiert wird. Somit werden Fehler im Code erst zur Laufzeit bekannt. Im Gegensatz zu C++ werden hier nicht schon viele Fehler durch einen Compiler abgefangen. Zusätzlich kann QML durch Javascript angereichert werden. Auch Javascript wird zur Laufzeit interpretiert und bietet keine Typsicherheit. Automatisierte Tests sind dadurch bei QML Anwendungen noch wichtiger als bei reinen C++ Projekten! Im Falle der Benutzeroberfläche für den digitalen Laser-Controller haben wir uns für automatisierte Tests mit dem GUI Testwerkzeug Squish der Firma Froglogic entschieden. Squish hängt sich direkt an Qt und kennt die interne Struktur von Qt, dessen Objekten und Events. Die Tests wurden in das Buildsystem mit Jenkins integriert und nach jeder Änderung automatisch ausgeführt. Ein Build ist nur erfolgreich wenn auch die Tests alle erfolgreich durchgelaufen sind. Nun ist die Frage: Wie viele Tests schreibt man? Wann sind genug Tests vorhanden? Abbildung 12: Beispielhafte Verlaufsdarstellung der QML Abdeckungsmetrik – wurde bei diesem Projekt so mit in Jenkins integriert.
  7. 7. Jahn Fuchs, Zühlke Engineering GmbH | Aus dem Projektalltag: Embedded Multitouch mit QML/QtQuick 2 7 Als ein Test Abbruchkriterium bei unseren GUI Tests haben wir uns die QML Abdeckungs-metrik ausgedacht. Dabei wird bei Ausführung der Test-Suite überprüft, wie viele von den im Gesamtprojekt existierenden QML Dateien über alle Tests geladen wurden. Schon alleine durch Laden aller QML Dokumente werden Syntaxfehler oder fehlende Grafiken im gesamten Projekt gefunden. Allerdings enthalten die meisten QML Dokumente auch Javascript. Für Javascript haben wir keine sinnvolle Metrik gefunden. Bisher ist es in Squish auch nicht möglich die Test-Abdeckung des Javascript Codes zu messen. Bei Gesprächen auf den Qt Developer Days mit Mitarbeitern von Froglogic zeigte sich, dass sie aber wohl schon intern an einer Lösung dafür arbeiten. . Über den Autor: Dipl.-Inf. Jahn Fuchs ist Software Engineer bei der Firma Zühlke Engineering GmbH und beschäftigt sich beruflich wie privat mit vielfältigen Themen aus der Software-entwicklung. Die Erfahrungsschwerpunkte und Interessen liegen im Bereich (embedded) Linux, C++, Oberflächenentwicklung mit Qt, Buildsystemen und Testinfrastrukturen. Wenn sich die Möglichkeit bietet hält er seit 2013 auch Vorträge über Themen, die ihn aktuell beschäftigen. Privat beschäftigt er sich neben der Technik am liebsten mit Gitarren, Poker und Tischfußball. Außerdem genießt er im Sommer gerne die Isar und das schöne München.

×