LightDroneCNC

Aus toolbox_interaktion
Wechseln zu: Navigation, Suche

Praktikumsarbeit des Studiengangs Elektro- und Informationstechnik im SS2013.

Lightdronecnc title.jpg

Das Team

Unser Team besteht aus drei Studierenden vom Studiengang Elektro- und Informationstechnik.

  • Jörg Biedermann
  • Christopher Lang
  • Christoph Rügheimer

Die Idee

Ein interaktives Lightpainting mittels Drohne.

Dem Benutzer soll es möglich sein, durch Malen in der Luft einen zweidimensionalen Pfad aufzuzeichnen, welcher anschließend von einem mit einer LED-Matrix bestückten Quadcopter abgeflogen wird. Der Pfad soll dazu zunächst, mit der Möglichkeit diesen zu editieren, visualisiert werden. Nach dem Startbefehl durch den Benutzer soll die Drohne dann starten.

Lightpainting

Grundidee hinter dem Projekt ist das so genannte Lightpainting. Hierbei wird mit einer (digitalen) Spiegelreflexkamera eine Langzeitbelichtung einer beliebigen Szene erstellt. Mit Hilfe einer Lichtquelle, wie zum Beispiel einer Taschenlampe, kann währendessen im Bild "gemalt" werden. Um ohne weitere Ausstattung angemessene Belichtungszeiten und einen hohen Kontrast zwischen Hintergrund und Schrift zu erreichen, empfiehlt es sich eine solche Aufnahme bei nahezu völliger Dunkelheit zu machen.

Hardware

Die Auswahl der Hardware fiel dabei auf die folgenden Komponenten:

Webkamera

Mit einer einfachen Webkamera, wie sie in fast jedem Notebook zu finden ist. Wird der Pfad aufgezeichnet. Als Alternative kann auch eine Webkamera über USB verwendet werden.

Parrot AR.Drone 2.0

Die AR.Drone 2.0 der Marke Parrot ist ein WiFi basierter Quadcopter, welcher mittels Smartphone, Tablet oder auch PC gesteuert werden kann.

Neben einer eigenen App stehen auch zahlreiche Open Source-Projekte zur Verfügung, welche sich mit der Steuerung und Erweiterung der Drohne beschäftigen. Dies und auch der vergleichsweise günstige Anschaffungspreis sprechen für den Einsatz der AR.Drone im Projekt.

Rainbowduino V3.0

Der Rainbowduino ist eine Arduino-Plattform mit integrierten LED-Treibern. Eine 8x8 RGB LED-Matrix ermöglicht es, jede LED einzeln anzusteuern. So können Sketches mit mit bis zu 16,7 Mio. verschiedenen Farben programmiert werden.

Durch das geringe Gewicht von etwa 10 Gramm und die hohe Farbvielfalt und Leuchtkraft ist der Rainbowduino für das Prjekt bestens geeignet.

Dies bestätigte sich auch in einigen Tests, bei denen Langzeitbelichtungen (15", f11) mit verschiedenen Farbverläufen aufgenommen wurden.

Das System

Das System besteht im wesentlichen aus vier Komponenten. Dazu zählt die Eingabe via Webcam, die Bildverarbeitung in EyesWeb, die Datenverarbeitung und -visualisierung in OpenFrameworks und die Ausgabe durch die Parrot AR.Drone.

Die Kommunikation zwischen den einzelnen Instanzen ist dabei wie im folgenden Schaubild aufgebaut:

Die Realisierung

Bildaufnahme

Zur Aufnahme des Bildes wird die im jeweiligen Laptop integrierte Webcam genutzt. Alternativ kann auch eine externe (Web-)Cam via USB angeschlossen und in EyesWeb als Eingabegerät konfiguriert werden.

Während der Tests hat sich gezeigt, dass die unten gezeigte Art der Selektion auch bei unruhigem Hintergrund meist zuverlässig funktioniert.

Um eine möglichst sichere Selektion zu gewährleisten empfiehlt es sich dennoch, die Webcam und den Nutzer vor einem neutralen und gleichmäßigem Hintergrund zu platzieren. Der Stift, welcher als "Eingabegerät" fungiert, sollte nicht zu klein sein und sich in der Farbe deutlich vom Rest des Bildes unterscheiden.

Bildverarbeitung

Die Bildverarbeitung findet in EyesWeb statt. Als Endprodukt der Verarbeitung sollen die x- und y-Koordinate des Stiftes via OSC an OpenFrameworks übergeben werden.

Zum leichteren Verständnis wurde der Patch in drei übersichtliche Teile gegliedert.

Um ein leichteres Finden der verwendeten Blöcke in der EyesWeb Bibliothek zu ermöglichen, werden diese jeweils in Anführungszeichen genannt.

EyesWeb


Schritt 1: Blob nach Farbe filtern

Der "FrameGrabber" liefert als Input das aktuelle Bild der Webcam.

Um das Tracking möglichst unbeeinflusst von dem vorhandenen Stift, den herrschenden Lichtverhältnissen im Raum und damit auch der Farbtemperatur zu machen, wurde eine "Snapshot"-Funktion eingebaut. Diese überträgt einen Frame der Webcam an das "MouseClickDisplay", wo über einen Klick die Koordinaten des gewählten Pixel ausgegeben werden.

Ein "GetPixel"-Element liefert dann den im Bild dazugehörigen Farbwert an den "ExtractColorBlobs".

Schritt 2: Blob nach Größe filtern und ins Bild zeichnen

Hier wird der größte Blob selektiert und mit Hilfe der "DrawBlob"-Funktion in der durch den "ImageGenerator" vorgegebenen Farbe ins Bild gezeichnet.

Schritt 3: Median Filter

Da das Bild zu diesem Zeitpunkt der Verarbeitung noch viele Punktstörungen enthält, welche zum späteren Zeitpunkt einen präzisen und gleich bleibenden Schwerpunkt verhinden würden, wird hier eine Filterung durchgeführt.

Der verwendete "ImageMedianFilter" hat dabei eine Maske von 13x13 px, was auch größere Störungen entfernt.

Schritt 4: Schwerpunkt berechnen

Mit "Baricenter" wird an dieser Stelle der Schwerpunkt des verbliebenen Blobs berechnet und durch ein "DrawGraphicObject" an der entsprechenden Koordinate ins Bild gezeichnet.

Da durch Aussetzer der Webcam oder auch das Eintauchen des Stiftes in Licht- oder Schattenbereiche Ausreißer in den Schwerpunktkoordinaten entstehen können, müssen diese Werte herausgefiltert werden. Dazu werden dem "Point2DGenerator" für die x- und y-Koordinate ein Wert von 0,01 vorgegeben. Der ausgegebene Punkt wird über eine "Comparison" mit den aktuellen Koordinaten verglichen. Ist der aktuelle Wert kleiner, als der vorgegebene Wert, wird der "Switch" geöffnet und die Koordinate somit aussortiert.

Anschließend werden durch "GetPoint2DCoordinates" die x- und y-Koordinate aus dem zweidimensionalen Punkt separiert.

Schritt 5: Filtern der Werte

In einem "TimeSeriesGenerator" werden jeweils 5 der x- und y-Koordinaten gepuffert und danach in einer "TimeSeries2Matrix" abgelegt.

Um leichte Abweichungen in den Pfadkoordinaten auszuschließen und diesen so zusätzlich noch etwas zu glätten, werden die Vektoren mit den jeweils 5 Werten nochmals durch einen Median Filter geführt.

Schritt 6: Ausgabe der Daten

Die Ausgabe der Daten erfolgt, neben der direkten Ausgabe der Werte über ein "ScalarDisplay", auch über ein "ScalarValueVsValueDisplay", welches als einfaches Koordinatensystem den Pfad gut visualisiert.

Um die Werte an OpenFrameworks zu übertragen kommt hier der "OSCClient" zum Einsatz. Die Konfiguration dessen kann dem EyesWeb File entnommen werden.

Schritt 7: Testen der OSC Schnittstelle

Da die Steuerung der Drone und auch die Benutzeroberfläche zu diesem Zeitpunkt noch nicht in OpenFrameworks realisiert war wurde, um die Verbindung zu überprüfen, ein "OSCServer" eingefügt.

Grafische Benutzeroberfläche

Klassendiagramm

Klassendiagramm LightDroneCNC.png

Am Anfang eines solchen Projektes haben wir uns erst einmal ein gutes Desgin überlegt und die einzelnen Komponenten in verschiedene Klassen aufgeteilt. Die Klasse FlightController kümmert sich um die Errechnung der Positionsvorgaben für die ARDrone. Die Klasse steuert den automatischen Flug der ARDrone indem Vorgaben über den aktuellen Liftspeed und den Rollwinkel gemacht werden. Diese Daten werden zyklisch an die ARDrone gesendet.

Die Klasse PointCollector stellt das Bindeglied zwischen Eyesweb und openFrameworks dar. Sie ist für den Empfang der OSC-Nachrichten zuständig und wertet diese aus. Anschließend werden aus den Daten einer Nachricht ein Objekt vom Typ DraggableVertex erzeugt. Die Zeiger auf die erzeugten Punkte werden in einem Container gespeichert. Diese Klasse bietet desweiteren Methoden um die enthaltenen Punkte zu verwalten. So kann über eine Methode der Status aller Punkte zurückgesetzt werden oder alle Punkte und somit die ganze Figur gelöscht werden.

Die Klasse DraggableVertex repräsentiert einen Punkt der von der ARDrone angeflogen werden soll. Dazu besitzt dieser Punkt Informationen über seine Position (x|y), jeweils normiert auf die Fensterbreite bzw. Fensterhöhe und über seinen "Zustand". Dieser Zustand gibt an, ob der Punkt bereits von der ARDrone angeflogen wurde oder noch nicht. Um ein Verschieben der Punkte in der Oberfläche zu ermöglichen, besitzt jeder Punkt Eigenschaften die in Abhängigkeit der aktuellen Mausposition gesetzt oder zurückgesetzt werden.

Die Klasse LightDroneCNC übernimmt die Hauptaufgabe in dieser Anwendung. Sie kümmert sich um die Darstellung der Oberfläche und zeichnet die Figur, bestehend aus mehreren Punkten, in das Fenster. Diese Klasse verarbeitet die Benutzereingaben und leitet, falls notwendig Ereignisse an ihre Komponenten weiter.


Benutzerschnittstelle

Die einzelnen auf der Oberfläche dargestellten Punkte könnten mit der Maus verschoben werden und so die aufgezeichnete Figur an die gewünschte Figur angepasst werden. Die Änderung der Position von einem Punkt wird abgespeichert und sofort angezeigt. Wenn man mit der Maus über einen Punkt fährt, wird die Positions vom Punkt innerhalb des Bildes angezeigt. Die Einheit der Koordinaten ist in Metern und verändert sich in Abhängigkeit von der eingestellten Bildgröße.

Ist die Kontur der Figur wie gewünscht korrigiert, dann kann durch das Drücken der Taste "Space" der automatische Flug der ARDrone gestartet werden. Zur Signalisierung der aktuellen Position der ARDrone wird die Stecke, die aktuell zurückgelegt wird rot gefärbt. Streckenabschnitte in der Farbe grün wurden bereits gefolgen und die schwarzen sind noch abzufliegen.

Nachdem die Figur abgeflogen wurde, kann man die Figur von der ARDrone erneut abfliegen lassen, Korrektur an einzelnen Punkten vornehmen oder aber die Figur verwerfen und mit der Aufzeichnung einer neuen Figur beginnen. Es ist auch möglich, zu einer bereits bestehende Figur weitere Punkte hinzuzufügen.

Ein manuelles Fliegen der ARDrone ist über die Benutzerschnittstelle auch möglich. Dabei sind sämtliche Richtungen über Tasten einzeln ansteuerbar. Angefangen vom Starten und Landen, über eine simple links - rechts - Bewegung hin zu einer Drehung um die eigene Achse. Diese Funktionen sind sehr gut geeignet, um die Drone an den gewünschten Startpunkt der Figur zu bewegen oder einfach nur Spaß am fliegen mit der ARDrone zu haben.

Quellen

Der Quellcode von der Anwendung "LightDroneCNC" kann hier heruntergeladen werden. Die Zipdatei beinhaltet das ganze Code::Blocks Projekt sowie die dazu notwendigen Addons von openFrameworks. Am besten den Ordner LightDroneCNC in das Verzeichnis "Installationspfad von openFrameworks"\apps\myApps kopieren. Dann die Projektdatei mit Code::Blocks öffnen, kompilieren und los gehts. Die Anwendung kann man auch nur dazu verwenden um die ARDrone manuell durch die Gegend fliegen zu lassen. Aber vorsicht, das verwendete Addon "ofxARDrone" für die Drone hat noch ein paar Schönheitsmängel. Im Ordner doxygen innerhalb der Zipdatei ist eine generierte Dokumentation aller im Projekt vorhandenen Klassen enthalten. Auch die einzelnen Klassen der Addons sind dort mit dokumentiert.

Lange Nacht der Wissenschaften 2013

Wir sind mit dabei und werden unsere Arbeit am 19.10.2013 dem breiten Publikum präsentieren :-)

Update

Das Projekt kam bei den Besuchern an der Langen Nacht der Wissenschaften sehr gut an. Groß und Klein waren begeistert von der Realisierung. Besondere Freude verbreitete die Möglichkeit, die AR.Drone mittels Tasten zu steuern. Im Rahmen der Vorbereitung für diese Veranstaltung wurden noch ein paar Kleinigkeiten ergänzt um auch eine Steuerung bei gedrückter Umschalttaste zu ermöglichen. Die aktuelle Software ist auf dem Server verfügbar.

Unser Fazit

Wir haben bei der Durchführung des Projektes eine Menge gelernt, sei es nun wie kommt man, nur mit einer so gut wie nicht vorhandenen Dokumentation *ggg*, mit Eyesweb zu recht. Auch die Frage wie realisiert man eine OSC-Kommunikation zwischen Eyesweb und openFrameworks können wir nun beantworten. Vieles aus der Vorlesung konnten wir in der Praxis anwenden und unser Wissen so vertiefen.


Probleme die es noch zu beheben gilt:

  • Steuerung über das Addon ofxARDrone von Openframeworks ist sehr rudimentär (nur Einwegkommunikation, keine Navigationsdaten). Zur Problemlösung könnte das Projekt cvDrone, welches auf OpenCV aufbaut, verwendet werden. In diesem sind zum jetzigen Zeitpunkt schon die Navigationsdaten implementiert und es ist auch möglich auf den Videostream der Drohne zuzugreifen. Vielleicht werden die Navigationsdaten auch in einer zukünftigen Version von ofxARDrone implementiert (da in diesem Bereich schon Anstrengungen unternommen wurden).
  • Die Anfangs gedachte Ausrüstung der Drohne mit Rainbowduino und 9V-Block funktioniert selbst bei optimaler Gewichtsverteilung - Rainbowduino vorne an der Kamera und 9V-Block im Heck der Drohne untergebracht - nicht. Probleme treten dann selbst bei Handsteuerung der Drohne auf und diese stürzt ab. Die Ursache ist, dass das System der Drohne instabil wird. Ein Vorschlag zur Behebung für dieses Problem ist, das gesamte Gewicht in die Mitte der Drohne zu verlagern (Drohne ist aber schon stark mit dem Heben der Last beschäftigt). Eine Alternative Lösung ist nur einer LED in der Front zu verbauen, sowie eine passende Knopfzelle zur Stromversorgung zu verwenden.


Hervorheben möchten wir, dass wir bei dem ganzen Projekt stehts von den Betreuern im vollen Umfang unterstützt wurden.

Downloads

Projekt Code::Blocks

Patch Eyesweb

Klassendiagramm LightDroneCNC

Klassendiagramm ofxARDrone

Klassendiagramm ofxNetwork

Klassendiagramm ofxOsc

Enterprise Architekt

HTML Export Enterprise Architekt