embedded multitouch (hmi 2014)

7
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 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

Upload: zuehlke

Post on 04-Dec-2014

178 views

Category:

Software


5 download

DESCRIPTION

Aus dem Projektalltag: Embedded Multitouch mit QML/QtQuick 2

TRANSCRIPT

Page 1: Embedded Multitouch (HMI 2014)

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

• 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

Page 2: Embedded Multitouch (HMI 2014)

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.

Page 3: Embedded Multitouch (HMI 2014)

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.

Page 4: Embedded Multitouch (HMI 2014)

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.

Page 5: Embedded Multitouch (HMI 2014)

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

Page 6: Embedded Multitouch (HMI 2014)

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.

Page 7: Embedded Multitouch (HMI 2014)

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.