Techniken und Tools Modellbasiert entwickeln im Internet of Things

Autor / Redakteur: Tamas Szabo und Dr. Klaus Birken* / EP Online

Bedingt durch das Internet der Dinge gibt es viele neue Anforderungen und – vor allem – viele neue Standards und Technologien, die vom Embedded-Entwickler beherrscht werden wollen.

Firma zum Thema

Roboterarm-Steuerung als Beispiel für ein Embedded-Software-System.
Roboterarm-Steuerung als Beispiel für ein Embedded-Software-System.
(Bild: itemis AG)

In diesem Beitrag wird an einem kompletten, realitätsnahen Beispiel gezeigt, wie die Methodik der modellbasierten Entwicklung dem Architekten und Entwickler hilft, diese Herausforderungen zu bewältigen. Im Beispiel wird ein realer Roboterarm über eine Embedded-IoT-Middleware von einem HTML5-Benutzerinterface gesteuert. Als IoT-Middleware wird MQTT eingesetzt; für die Code-Generierung von Teilen der Oberfläche und der Kommunikation wird das Open-Source Framework Franca verwendet.

Bildergalerie

Embedded-Entwicklung für das Internet der Dinge

Der Begriff „Internet der Dinge“ (engl. Internet of Things, kurz IoT) beschreibt die Vernetzung von mobilen Geräten, Server-Infrastrukturen und Gegenständen des menschlichen Alltags. Dabei entstehen neue, übergreifende Anwendungen und Systeme, die bisher in dieser Form nicht möglich waren. Da Embedded-Systeme einen wichtigen Teil dieser neuen Anwendungen ausmachen, ist die Welt der Embedded-Entwicklung vom IoT-Trend massiv betroffen.

Dies erschließt neue Einsatzbereiche und Umsatzfelder für die zu entwickelnden Geräte und ist somit zunächst positiv zu sehen. Für die Embedded-Entwickler hält dieser Trend jedoch vielfältige Herausforderungen bereit: Technologien wie webbasierte Oberflächen oder Vernetzung mittels Internettechnologien halten Einzug in das zu beherrschende Technologie-Portfolio. Dazu gehören HTML5, JavaScript oder WebSockets auf der UI-Seite, aber auch Protokoll-Implementierungen und serverseitige Softwarebausteine wie z.B. MQTT.

Bei diesen neuen Herausforderungen der Entwicklung für das Internet der Dinge helfen modellbasierte Methoden: Durch die Erstellung von Modellen wird auf einer abstrakteren Ebene gedacht und entwickelt, als dies bei der reinen Programmierung durch Source-Code möglich wäre. Die zu beherrschenden Technologien werden zwar nach wie vor als Teil der Systeme verwendet, können jedoch von Codegeneratoren umgesetzt werden. Diese Codegeneratoren nehmen die Modelle als Eingabe und produzieren effizienten, schlanken Code zur Anbindung der handgeschriebenen Applikationssoftware an die vorgegebenen Kommunikations-Stacks und Bibliotheks-APIs (kurz für Application Programming Interface).

Der besondere Fokus bei der modellbasierten Entwicklung von IoT-Architekturen sollte auf den Schnittstellen des Systems liegen. Diese stellen die logische Verbindung zwischen den Teilsystemen und Komponenten her. Wenn die Schnittstellen sauber modelliert sind, können die verschiedensten zu integrierenden Teilsysteme (z.B. Libraries, Stacks, Applikationskomponenten) wie Bauklötze zusammengesetzt werden.

In diesem Beitrag wird beschrieben, wie ein solcher modellbasierter Ansatz durch das Open-Source-Projekt Franca unterstützt wird. Dazu wird ein Beispielsystem aufgebaut, das aus einer webbasierten Benutzeroberfläche, einem Roboterarm und einer dazwischenliegenden IoT-Middleware besteht. Die Schnittstellen in diesem System wurden mit Franca [1] modelliert; aus den Schnittstellen wurde Source-Code generiert, der die Teilsysteme des Beispiels elegant verbindet.

Interface Definition Languages (IDLs)

Gerade vor dem Hintergrund der oben beschriebenen Herausforderungen ist es für ein erfolgreiches Projekt wichtig, die Schnittstellen zwischen Komponenten, Subsystemen oder Systemen einer IoT-Landschaft nicht direkt als C-Header-Dateien zu entwerfen und zu repräsentieren, sondern auf einer höheren Abstraktionsebene, die von der Programmiersprache unabhängig ist.

Dies wird durch eine Beschreibungssprache für Schnittstellen oder IDL (kurz für: Interface Definition Language) möglich [2]. Diese reduziert die Syntax auf genau das Vokabular, das für die inhaltliche Definition von Schnittstellen gebraucht wird. Die Abbildung auf eine Programmiersprache geschieht typischerweise durch Codegenerierung.

Alle verfügbaren IDLs erlauben es, Schnittstellen (relativ) unabhängig von der Zielplattform und -sprache formal zu beschreiben. Damit können dieselben Schnittstellen zur Integration über Subsysteme, Programmiersprachen, Controller und Steuergeräte hinweg eingesetzt werden. Schnittstellen werden so ein übergreifendes Werkzeug für Architekten und Entwickler.

Der typische Sprachumfang einer IDL deckt die statischen Anteile von Schnittstellen ab. Zu den statischen Anteilen gehören Datentypen, Attribute und Funktionsaufrufe. Dies ist zur Dokumentation der Schnittstelle und auch zur Codegenerierung ausreichend, da in den typischen Programmiersprachen ebenfalls nur statische Anteile von Schnittstellen beschrieben werden (C-Header oder C++-Klassen enthalten keine Festlegung z.B. von Aufrufreihenfolgen).

Die dynamischen Anteile von Schnittstellen werden heute meist erst in der Implementierung berücksichtigt. Zu den dynamischen Anteilen gehören Aufrufreihenfolgen (also Sequenzen) und die erlaubten Parameterwerte in jedem Schritt. Ebenfalls gehören z.B. nicht-funktionale Eigenschaften wie Timing-Restriktionen zu den dynamischen Anteilen. Gerade für komplexere Systeme ist es sinnvoll, die dynamischen Anteile bereits als Teil der Schnittstellendefinition festzulegen [3]. Dies bringt die Qualität der Software-Entwicklung auf eine neue Ebene. Der Schnittstellen-Designer hat die genaueste Vorstellung davon, wie seine Schnittstelle zu verwenden ist. Über die formale Festlegung der Dynamik kann er dies den nachfolgenden Implementierern übermitteln. Dies steigert die Qualität des resultierenden Softwaresystems.

Das Open-Source-Werkzeug Franca

Im Rahmen des GENIVI-Konsortiums [4] wurde mit Franca [1] eine IDL entwickelt, deren wichtigstes Entwurfsziel die Einsetzbarkeit in verschiedensten Umgebungen ist. Das GENIVI-Konsortium entwickelt eine standardisierte Plattform für Automotive/Infotainment-Systeme. Die Software für ein solches System kommt mehr und mehr von verschiedenen Zulieferern, somit ist die Entwicklung zum großen Teil auch eine Integrationsaufgabe. Um die geforderte Interoperabilität von Komponenten und Subsystemen zu gewährleisten, wurde eine Schnittstellenbeschreibungssprache und eine zugehörige Werkzeugumgebung incl. Framework entwickelt und als Open-Source Projekt Franca auch außerhalb von GENIVI verfügbar gemacht.

Abbildung 1 zeigt eine Übersicht der Funktionen, die Franca bietet. Zentrales Element ist die plattformunabhängige IDL mit einem komfortablen Editor. Franca unterstützt weiterhin die Erstellung von Generatoren und Modell-zu-Modell-Transformationen. Beide Aspekte sind detailliert in [2] beschrieben.

Bild 1: Franca bietet neben einer IDL weitere Funktionen und Vorteile.
Bild 1: Franca bietet neben einer IDL weitere Funktionen und Vorteile.
(Bild: itemis AG)

Franca unterstützt ebenfalls die Beschreibung des dynamischen Verhaltens von Schnittstellen. Dazu bietet Franca IDL die Möglichkeit, Kontrakte von Schnittstellen in Form von Protokoll-Zustandsautomaten zu spezifizieren. Dies sind Zustandsautomaten, die auf der Verbindung zwischen den beiden kommunizierenden Softwareteilen (z.B. Komponenten) angesiedelt sind und auf Kommunikationsereignisse in beiden Richtungen reagieren.

Franca IDL ist eine domänenspezifische Sprache (DSL); somit sind Schnittstellendefinitionen mit Franca IDL Textdateien, die genauso wie Quellcode behandelt werden können [5]. Die Versionsverwaltung kann mit den gewohnten Werkzeugen (z.B. git oder Subversion) gelöst werden. Dateivergleich und merge-Operationen sind wie gewohnt möglich. Zur statischen Definition von Schnittstellen bietet Franca u.a. folgende Konzepte:

  • Attribute (Datenelemente mit Observer-Mechanismus), Methoden (bidirektionale Kommunikation) und Broadcasts (server-initiierte Kommunikation)
  • primitive Datentypen und benutzerdefinierte Datentypen (Strukturen, Felder, Enumerations u.a.)

Ein wichtiger Bestandteil der Franca Open-Source-Release ist ein Editor, der die Syntax der IDL kennt und dem Entwickler eine Vielzahl von hilfreichen Funktionen anbietet. In Abbildung 2 (siehe Bildergalerie) ist der Franca-IDL-Editor mit einigen seiner Funktionen gezeigt. Während des Editierens läuft eine Validierung, die Fehler sofort anzeigt. Das Beispiel zeigt ein Franca-Interface mit den wichtigsten Bestandteilen. Im Beispiel sind Fehlermarker in den Zeilen 12 und 16 erschienen, die auf einen ungültigen Typ hinweisen. Beim Cursor in Zeile 29 wurde ein Content-Assist-Fenster aufgerufen, das alle an dieser Stelle gültigen Eingaben als Vorschlag anbietet. Weitere Funktionen sind Syntax-Coloring, Folding, Jump-to-Definition und Show-References.

Technologien für das Internet der Dinge

Das Internet der Dinge ist ein verteiltes, dynamisches System (eigentlich: System of Systems); deshalb ist die verwendete Kommunikationstechnologie ein wichtiger Aspekt zur Implementierung solcher Systeme. Für das hier beschriebene Beispiel verwenden wir das MQTT-Protokoll [6]. MQTT (kurz für: Message Queue Telemetry Transport) ist ein Nachrichten-Protokoll, das auf TCP/IP aufsetzt und ein publish/subscribe-Schema umsetzt. Das leichtgewichtige Protokoll ist für sehr beschränkte Ressourcen und unzuverlässige Verbindungen konzipiert. Es setzt verschiedene Quality-of-Service-Konfigurations-Möglichkeiten um. Die Eclipse-Foundation bietet mit dem Eclipse IoT-Projekt mehrere Open-Source-Projekte und -Tools an, die eine Implementierung von Systemen mittels MQTT unterstützen. Für unsere Beispielumsetzung verwenden wir folgende Tools:

  • Mosquitto [7]: eine Implementierung der MQTT-Serverseite, ein sog. „Message broker“
  • PAHO [8]: eine Implementierung der MQTT-Clientseite, verfügbar für mehreren Zielsprachen (z.B. C, C++, JS, Java, Lua)

Durch die Verwendung dieser Open-Source-Tools lässt sich eine Beispiel-IoT-Anwendung ohne große Kosten umsetzen.

Eine verteilte Roboter-Steuerung mit Web-User-Interface

Als Beispiel für eine IoT-Anwendung bauen wir eine verteilte Steuerung für einen Roboter-Arm auf. Die Roboter-Hardware ist ein AL5D-Kit von Lynxmotion mit SSC32-Steuerplatine. Abbildung 3 zeigt den Roboterarm; dieser besteht aus fünf Achsen und einer Greifeinheit. Die Steuerplatine dient der komfortablen Ansteuerung der Motoren und ist ihrerseits über ein serielles Protokoll mit einem Hostrechner verbunden. Der Hostrechner kann z.B. ein Raspberry PI, ein beliebiges anderes Microcontroller-System oder ein PC sein.

Der Roboterarm wie in Abbildung 3 dargestellt realisiert folgende Funktionalität:

  • Der Greifer kann Objekte festhalten und loslassen.
  • Der Arm kann den Greifer an eine bestimmte kartesische Position bewegen.
  • Der Anstellwinkel und Drehwinkel des Greifers sind in bestimmten Grenzen frei wählbar.

Die Architektur der gesamten IoT-Anwendung ist in Abbildung 4 (siehe Bildergalerie) dargestellt. Die RobotArm-Hardware incl. der Steuerplatine (wie oben beschrieben) wird von einem in Java implementierten Robot Client gesteuert. Die RobotArm-Applikation auf dem Robot-Client-Rechner stellt die Basis-Funktionalität zur Steuerung des Roboters über einen MQTT-Server bereit. Dabei werden MQTT-konform sog. Topics auf dem Server publiziert, durch deren Ansteuerung ein Client den Roboterarm verfahren und den Greifer steuern kann. In einer realen Produktionsumgebung müssten noch Aspekte wie Zugriffssicherheit, Sensorik oder Bildverarbeitung berücksichtigt werden. Um das Beispiel einfach zu halten, beschränken wir uns derzeit auf die reinen Steuerungsaspekte.

Aus Benutzersicht stellt unsere IoT-Anwendung ein webbasiertes User Interface bereit, das die Robotersteuerung auf zwei Ebenen erlaubt:

  • Von einem Benutzer in der Rolle des Maschineneinrichters kann der Roboterarm in seinen grundlegenden Funktionen bedient werden (z.B. Fahren auf Position, Greifen)
  • Von einem Benutzer in der Rolle eines System-Bedieners kann der Roboterarm für die Umsetzung von komplexen Abläufen benutzt werden (z.B. Bewegen eines Objekts von A nach B).

Das User-Interface kann auf einem normalen Web-Browser ablaufen. Es ist über eine Websockets/WAMP-Schnittstelle [9] mit dem GUI Client verbunden. Dieser implementiert die Fachlogik zwischen UI und der über MQTT zur Verfügung gestellten Roboter-Schnittstelle. In unserem Beispiel ist der GUI-Client in JavaScript (kurz: JS) implementiert.

Die IoT-Anwendung ist also physikalisch auf folgende Systeme verteilt:

  • Roboterarm-Hardware
  • Roboterarm-Steuerung und Bereitstellung über MQTT (Robot Client)
  • MQTT-Server
  • Fachlogik und Ansteuerung über MQTT (GUI Client)
  • Browser (benutzerseitig)

Modellbasierte Implementierung mit Franca

In der oben beschriebenen IoT-Architektur gibt es mehrere Schnittstellen zwischen Teilsystemen, die in der Verantwortlichkeit von verschiedenen Unternehmen oder organisatorischen Einheiten liegen. Für diese Schnittstellen ist es sinnvoll, sie nicht nur über eine Freitext-Dokumentation zu definieren, sondern formal über eine modellbasierte Beschreibungssprache, also eine IDL. Franca erfüllt diese Anforderungen. Die formale Beschreibung bringt dabei folgende Vorteile:

1. Die Semantik der Schnittstelle ist klar definiert und dient dabei als Kontrakt zwischen den beteiligten Systemlieferanten.

2. Aus der formal definierten Schnittstelle kann direkt die Software für die Kommunikation zwischen den Systemen generiert werden. Dies schließt Fehler durch händische Implementierung aus und erlaubt zusätzlich die Wiederverwendung von Optimierungen, da diese nur im Generator durchgeführt werden.

3. Aus der gleichen formalen Beschreibung können Kommunikations-Stacks in verschiedenen Programmiersprachen und Kontexten generiert werden. Im Beispiel sind dies zwei MQTT-Implementierungen in Java und JS sowie die Verbindung einer HTML5-UI im Browser mit der Fachlogik-Implementierung.

4. Die formal definierte Schnittstelle kann zur Erstellung von Integrations- und Systemtests dienen. Diese können z.B. in einer Scriptsprache wie Lua oder Python erstellt und gegebenenfalls sogar generiert werden.

5. Wird die formale Beschreibung um die dynamische Sicht erweitert (also z.B. erlaubte Kommunikations-Sequenzen wie oben beschrieben), so können weitergehende Tests zur Qualitätssicherung umgesetzt werden.

In der beispielhaften IoT-Anwendung wurden die Schnittstellen zwischen webbasiertem Benutzerinterface und Fachlogik über Franca IDL definiert. Die Franca-Schnittstellendefinition für die grundlegende Bedienung der Roboterfunktionen ist in Abbildung 5 (siehe Bildergalerie) dargestellt. Das Franca-Tool enthält einen Codegenerator, der aus dieser Beschreibung die client- und server-seitigen Kommunikations-Stacks über die Standards WebSockets und WAMP automatisch generiert (Zielsprache ist JS). Damit ist für die Implementierung der Kommunikation zwischen Browser und Fachlogik-Client keine manuelle Arbeit nötig. Auf der Browser-Seite kann der HTML5-Code elegant an die generierten Proxy-Komponenten zur Kommunikation angebunden werden. Auf der Server-Seite der WebSockets (gleichzeitig Client-Seite für die MQTT-Kommunikation) werden hauptsächlich Callbacks mit Leben gefüllt, die vom Franca-Codegenerator vorbereitet wurden.

Ein ähnliches Prinzip kann für die Kommunikation über die MQTT-Strecke angewendet werden. Auch hier wird zunächst ein Franca-Interface definiert, aus dem dann der Java- und JS-seitige Client-Code für die benötigten MQTT-Topics generiert wird. Die Abbildung von Franca-Interfaces auf MQTT-Topics wird einmal grundsätzlich bei der Entwicklung des Codegenerators gelöst und kann dann für jede neue Anwendung einfach wiederverwendet werden.

Vorteile der modellbasierten Methode für den Entwickler von IoT-Anwendungen

Die modellbasierte Definition von Schnittstellen ist gerade bei stark verteilten Anwendungen notwendig und sinnvoll. Durch Franca IDL können die Schnittstellen formal definiert werden und dienen dann als maschinenlesbarer „Vertrag“ für die beteiligten Parteien und Systeme. Aus den zuvor definierten Schnittstellen können Teile des Programmcodes automatisch generiert werden. Dies erlaubt zudem die Kombination von verschiedenen Technologien und Sprachen – dies ist der Normalfall bei Anwendungen für das Internet of Things. Die Integration der verschiedenen Subsysteme fällt dadurch erheblich leichter, weil die Kompatibilität der Teilsysteme durch die formale Schnittstellendefinition sichergestellt wird.

Franca ist unter [1] für jedermann verfügbar und kann inclusive Dokumentation frei heruntergeladen und direkt eingesetzt werden. Auch der beschriebene Generator für Websocket/WAMP-Kommunikation ist in der Distribution enthalten. Die Technologien für die Umsetzung einer MQTT-Kommunikation sind unter den angegebenen Links ebenfalls frei verfügbar.

Referenzen

[1] http://code.google.com/a/eclipselabs.org/p/franca/

[2] K. Birken: Schnittstellen voll im Griff – Modellbasierte Ansätze mit dem Open-Source-Werkzeug Franca. In: Tagungsband – Embedded Software Engineering Kongress 2012, Sindelfingen, 2012.

[3] K. Birken: Interfaces dynamisch beschreiben mit Franca. In: Tagungsband – Embedded Software Engineering Kongress 2013, Sindelfingen, 2013.

[4] http://www.genivi.org

[5] K. Birken: Domänenspezifisch modellieren, nicht nur zur Codegenerierung. In: Tagungsband – Embedded Software Engineering Kongress 2010, Sindelfingen, 2010.

[6] http://mqtt.org

[7] https://projects.eclipse.org/projects/technology.mosquitto

[8] https://www.eclipse.org/paho/

[9] WebSockets-Standard RFC 6455, http://tools.ietf.org/html/rfc6455

* Tamas Szabo arbeitet als Software-Ingenieur bei der itemis AG mit dem Schwerpunkt auf modellbasierten Methoden und Tool-Entwicklung.

* Dr. Klaus Birken ist als Berater und Teamleiter bei der itemis AG tätig.

(ID:44023335)