Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste

abgeschlossene_projekte:drinkbot

Projektdokumentation

drinkBot [MVK1]

Beteiligte:

bis zum Schluss dabei:

  • Feven Zeru
  • Owain Neumann
  • Max-Lennart Leistikow

unterwegs verlustig gegangen:

  • (Leonard von Kleist)
  • (Laurin Rolli)
  • (Constantin Opel)
  • (Emely Erdbeer in Klammern)

Zusammenfassung:

Der drinkBot erkennt den Mund einer Person, fährt zu der erkannten Position und flößt dem Bediener ein Getränk ein. Wir entwickelten den Roboterarm auf der Basis des Schachroboters Armin. Unser Roboter kann über eine eigens entwickelte Andriod/Apple-App bedient werden. Nach Programmstart fährt der Roboterarm mit dem an ihm befestigten Schlauchende zum Mund des Durstigen. Auf Knopfdruck öffnet sich ein Magnetventil und das Getränk fließt in den Mund. Nach dem Beenden des Programms fährt der Arm zurück in die festgelegte Ausgangsposition.

Hauptseite

Themenbeschreibung/Einleitung

Die Aufgabe des drinkBots ist es, den Nutzer durch das Zuführen von Flüssigkeiten in einen entdursteten Zustand zu versetzen. Die Kommunikation zwischen dem Nutzer und dem drinkBot läuft über das Smartphone des Nutzers. Dafür ist die App TouchOSC notwendig. Nachdem das richtige Bedienfeld auf dem Smartphone installiert ist, kann es losgehen. Nach Betätigung des Start/Stop Schalters auf dem Smartphone wird auf dem Computer ein Programm gestartet, welches dem drinkBot mitteilt, das Gesicht des Nutzers zu suchen. Nun muss das Programm durch ständiges überprüfen der Mundposition die Servos so bewegen, das der Schlauch sich zum Mund des Nutzers hinbewegt. Die Mundposition wird durch eine Munderkennungssoftware (open-source) berechnet und von einer Webcam erfasst. Die Webcam befindet sich am Arm des Roboters. Durch das Drücken des grünen Knopfs auf dem Bedienfeld (gedrückt halten!) wird nun der Zufluss gestartet und der Nutzer kann seinen Durst befriedigen. Der Zufluss kann so oft wie gewünscht gestartet und gestoppt werden. Ist der Nutzer zufrieden, kann er durch ein erneutes Betätigen des Start/Stop Schalters den drinkBot in seine Ursprungsposition zurückversetzen. Der gesamte Vorgang kann nun von vorne gestartet werden.

Da die Bereitstellung dieser Funktionen mehrere Programme benötigt, war es notwendig eine Kommunikation zwischen diesen Programmen herzustellen. Und genau das ist der Punkt, wo die ganze Sache etwas technischer wird. Wir versuchen das hier jedoch möglichst verständlich darzustellen. Damit wir diese Kommunikation herstellen können, muss eine Datenübertragung zwischen den Programmen stattfinden. Dies erfolgt über ein so genanntes Protokoll Namens OSC (Open Sound Control), welches über W-LAN übertragen wird. Total vereinfacht könnte man sagen, dass die Programme tatsächlich miteinander sprechen. So bekommt eines der auf den Computer laufenden Programme (Processing) vom Smartphone mitgeteilt, wenn z.B. der Start/Stop Schalter betätigt wurde. Die Reaktion darauf ist dann, dass Processing dem Roboter (auf Arduino basierend) diese Information nun weiterleitet. Dies tut Processing jedoch in einer anderen „Sprache“. Processing fungiert also als eine Art Übermittler der Information. Dieser „Übermittler“ ist aber notwendig, da das Smartphone und der Roboter unterschiedliche „Sprachen“ sprechen.

Überblick über das Gesamtsystem

Hier ist das gesamte System schematisch und in unserer endgültigen Umsetzung zu erkennen.

Das „ausführende Organ“ ist der Roboterarm, der durch die 3 Servos bewegt wird, an dessen Spitze ein Schlauchende hinausragt und oben eine Kamera befestigt ist.

Die Kamera liefert das Kamerabild anhand dessen mithilfe eines Processing-Programms auf dem Computer die Position des Mundes im Raum ermittelt werden kann. Mithilfe dieser Koordinaten berechnet ein weiterer Programmteil wie weit sich die Servos in welche Richtung drehen müssen, um den Mund anzusteuern.

Die errechneten Servowinkel werden über den Arduino und den Servo-controller an die Servos übermittelt. Sie drehen sich an die gewünschte Position.

In der Nähe des Roboterarms steht ein selbstgebautes Holzstativ als Flaschenhalter - auch genannt Krücke. Die erhöhte Flaschenposition wurde wichtig nachdem klar war, dass wir keine geeignete Aquariumpumpe für die Wasserversorgung auftreiben können. Die Flasche in dem Stativ ist über einen Schlauch mit einem Magnetventil verbunden, das über den Computer bzw. die App geöffnet werden kann. Von dort fließt das Getränk weiter durch den Schlauch bis zur Spitze des Roboterarms in den Mund des Durstigen.

Die Aquariumpume hätte das Wasser einfach in den Mund gepumpt, nun fließt das Wasser - bekanntlich immer bergab - zur trinkenden Person, so wird die Krücke elementar wichtig zur Nutzung des drinkBots: Je höher die Wasserflasche positioniert ist, desto stärker ist der Druck am Ende des Schlauchs.

Die Stromversorgung sowohl der Servos, als auch des Magnetventils wird hier über das Netzteil des Controllers gewährleistet.

Das Handy mit der App kommuniziert per WLAN mit dem Computer. Mit ihr kann das Programm gestartet und beendet werden. Sobald der drinkBot seine Endposition erreicht hat wird das Magnetventil hierüber per Knopfdruck geöffnet und schließt sich beim Loslassen wieder. Wird das Programm beendet, so bewegt sich der Arm in die Ausgangsposition zurück.

Hardware & Munderkennung

[Max]

Der Roboterarm war zwar schon aufgebaut, doch musste noch die Schaltung für die Servoansteuerung aufgebaut und die entsprechenden Softwarelibraries für die Munderkennung per Webcam und die Servosteuerung gefunden und installiert werden.

Munderkennung

Die Istallation der Bibliotheken funktioniert über den Contribution Manager in Processing. Eingebunden werden müssen die Libraries:

  • OpenCV for Processing
  • Video

Software & Quellcodes

Wir gingen zunächst vom Beispielprogramm der Gesichtserkennung von OpenCV aus. Das haben wir so verändert, dass nur der Mund (OpenCV.CASCADE_MOUTH) erkannt wird.

Des Weiteren fügten wir die Koordinatenberechnung ein. Von dem Programm werden zwar schon Koordinaten ausgegeben, diese gehören jedoch zur oberen linken Ecke des Kästchens, das um den Mund gezogen wird.

So errechnen wir den Mittelpunkt des Kästchens:

$x = xKoordinate + Kästchenbreite/2 $

$y = yKoordinate + Kästchenhöhe/2 $

Für bessere Übersichtlichkeit verlegen wir den Ursprung des Koordinatensystems aus der linken oberen Bildschirmecke in die Mitte. Bildgröße 320×240, d.h. vom Ergebnis nochmal je die Hälfte der Bildschirmhöhe & -breite abziehen.

$x = (xKoordinate + Kästchenbreite/2)-160 $

$y = (yKoordinate + Kästchenhöhe/2)-120 $

Das schwierigste an der Koordinatenbestimmung war die Berechnung der z-Koordinate per Strahlensatz für die 3D-Darstellung der Kameradaten.

Dem Strahlensatz zufolge erscheinen Objekte, die weiter von der Kamera entfernt sind im Kamerabild kleiner, als Objekte, die näher dran sind.

Da wir weder Brennweite, noch die Ausflösung des Bildsensors der Kamera kennen, schmeißen wir diese beiden Werte in eine zusammenhängende Konstante. Mithilfe dieser können wir in Zukunft die z-Koordinate ermitteln. Die Konstante selbst ermittelten wir analog mit Geodreieck und Zollstock: An verschiedenen Abständen zur Kamera ließen wir uns von der Munderkennungssoftware die Mund-Kästchenbreite ausgeben. Der Zollstock bzw. der Winkel mit Maßeinheiten und das Geodreieck fungierten zur Messung der Richtigen Abstände und Mundbreite (rechtes Bild).

Messung Entfernung zur Kamera [cm] im Bild gemessene Mundgröße [cm] in Pixeln ausgegebene Mundgröße [px] errechnete Konstante
1 15 5,5 140 381,81
2 20 5,5 116 421,81
3 25 6 100 416,666
4 30 6 80 400
Durchschnitt ~5,7 400

Daraus ergibt sich unsere Formel zur Berechnung der z-Koordinate:

$ z[cm]=(5,7*400)/Mundgröße[px] $

Die Mundgröße in Pixeln wird dabei von der Munderkennungssoftware geliefert. Sie ist im Programm eine Variable, da sie sich ständig ändert jenachdem wie weit der Mund von der Kamera entfernt ist. Diese Gleichung mit einer Variable wird von der Software in dem Moment genau berechnet, in dem der Mund erkannt wird.

Hardware

Da die Software zur Umrechnung der Kamerakoordinaten in Servowinkel noch in Arbeit war begann ich mich mit der Servosteuerung an sich zu beschäftigen. Vorhanden war schon die hölzerne Grundplatte mit aufgebautem 3-gliedrigen Roboterarm [ARMIN] vom letzten Semester. Die 3 Servos, die die Gelenke darstellen sind in Reihe geschaltet miteinander verbunden. An ihnen hin außerdem der Servocontroller (CDS55xx) zu dem es auch ein Netzteil gibt.

Den Anschlüssen zufolge wird ein Rx und ein Tx PIN mit dem Arduino und der dritte PIN mit GND verbunden. Der Arduino Nano hat diese Anschlüsse auch, aber die werden schon für die Datenübertragung Computer-Arduino benötigt. Deshalb ersetzen in unserem Fall die Digital-Pins D3 (-Tx am Controller) und D2 (-Rx am Controller) diese Funktion. Sie müssen nur in der Software rihtig eingesetzt werden - dazu gleich mehr.

Die Servos benötigen 12V. Da der Arduino nur max. 5V liefern kann, hat der Controller eine externe Stromversorgung über das Netzteil.

Das der Controller diese externe Stormversorgung hat machten wir uns gleich für das Magnetventil zunutze, denn auch das benötigt 12V. Um den Strom vom Controller 'abzuzapfen' mussten wir nur herausfinden welche PINs der Servoverbindungskabel für die Stromversorgung notwendig sind. (siehe Skizze). Beim Magnetventil ist darauf zu achten eine Diode (leitet Strom nur in eine Richtung) parallel zum Ventil zu schalten, damit mögliche Rückströme nicht erneut durch das Magnetventil fließen. Über einen MOSFET kann das Signal des digital PIN D10 das Magnetventil öfnnen/schließen. Hier ist zu beachten einen Widerstand zwischen Gate und Source zu schalten.

Die Schaltung sieht so aus (ist wahrscheinlich verständlicher, als alle meine schriftlichen Ausführungen):

Der Arduino ist über ein USB-Kabel mmit dem Computer verbunden. Für die Nutzung der Servos müssen hier eigene header-Dateien eingebunden werden:

  • DynamixelSoftSerial.h
  • SoftwareSerial.h

Software & Quellcodes

Die Servoansteuerung funktioniert ganz einfach. Es müssen nur Servonummer, gewünschte Position und Geschwindigkeit eingestellt werden:

  • Dynamixel.moveSpeed(ServoNr,Pos,Speed)

Die Servos können theoretisch sogar ihre Temperatur [Dynamixel.readTemperature(1)], Volt [Dynamixel.readVoltage(1)] und momentane Position [Dynamixel.readPosition] zurückmelden, was der Controller aber leider nicht unter stützt. (weitere Anwendungsbeispiele sind in der DynamixelSoftSerial.h hinterlegt)

Zum öffnen des Magnetventils wird auf den verbundenen PIN Spannung angelegt, durch den MOSFET fließt Strom und das Magnetventil wird mit Spannung versorgt und öffnet sich. Zum schließen einfach den belegten PIN wieder deaktivieren.

Ursprünglich wollten wir statt dem Magnetventil eine Aquariumpumpe einsetzen. Nachdem klar wurde, dass wir keine passende Aquariumpumpe für die Realisierung des Projektsfinden würden, musste eine andere Lösung her, die hieß Magnetventil.

Mit der Aquariumpumpe wäre es egal gewesen an wo wir den Behälter für das Getränk anbringen. Durch die Nutzung des Magnetventils war klar: Wir müssen die Flasche auf eine höhere Position als das Schlauchende bringen, damit das Wasser allein durch die Schwerkraft durch den Schlauch in den Mund des Konsumenten fließt.

Wir bauten also ein mobiles Holzstativ auf 3 Rädern mit einem Flaschenhalter am oberen Ende. Die kinetische Energie des Wassers in der Flasche reicht aus, um genug Druck aufzubringen, dass das Wasser aus dem unteren Ende des Schlauchs in Mund der trinkenden Person fließt.

Aus dieser abenteuerlichen Konstruktion entstand die Modellbezeichnung Magnetventil-Krücke (drinkBot [MVK]).

Software & Appentwicklung

[Owain/Leo]

Damit das ganze System auf den unterschiedlichen Plattformen parallel laufen und funktionieren konnte, war es notwendig eine Kommunikation zwischen den unterschiedlichen Programmen herzustellen. Dies wurde umgesetzt, indem wir OSC-Protokolle (Open Sound Control) zwischen den Programmen (und der App) über W-LAN versendeten. Dazu war die App TouchOSC notwendig. Des weiteren muss man die Bibliotheken

  • ControlP5
  • oscP5

über den Contribution Manager in Processing installieren und einbinden. (Software & Quellcodes)

Zu Beginn planten wir, dass wir die App zur Steuerung des Roboters selber programmieren. Nachdem wir einen Java Crashkurs belegt hatten wurde uns erst der Umfang dieser Idee bewusst. Daher legten wir die Aufgabe ab und widmeten uns der Suche nach einer Alternative. Dabei haben wir die App 'TouchOSC' gefunden, welche wir jetzt auch verwenden. Mit dieser App ist es möglich diese sogenannten OSC-Protokolle zu senden und zu empfangen, des Weiteren ermöglicht TouchOSC dieselben Funktionen für MIDI Pakete. Da wir letztere Funktionen aber nicht benötigen, werden wir auch nicht weiter darauf eingehen. Wie schon in der Einleitung geschildert, kann das Smartphone dank der App nun mit dem Programm auf dem Computer (Processing) kommunizieren.

Als Ansatzpunkt für unsere Arbeit suchten wir und ein Projekt, welches die Kommunikation zwischen Arduino und Processing nutzt. Dabei wurden wir auch fündig und konnten die vorhandenen Quelltexte und Vorgehensweisen übernehmen und überarbeiteten. Damit wir aber erst mal differenzieren konnten, was wir von dem Vorhandenen benötigen und welche Teile für uns unwichtig waren, mussten wir uns in die Materie einarbeiten und sehr viel ausprobieren und experimentieren. Dabei war Google unser Freund und Helfer. Die nächste Herausforderung war es, das Handy in den Prozess zu integrieren, da wir bisher lediglich die Kommunikation zwischen zwei Computerprogrammen zustande gebracht hatten. Hierbei war erneut Google gefragt, so suchten wir nach neuen Projekten und Dokumentationen bei denen Kommunikation über TouchOSC, bzw. allgemeine Arbeiten mit Open Sound Control Protokollen stattgefunden hat. Am Ende hatten wir dann einen aus vielen Teilen zusammen geflickten Quelltext, der dadurch aber auch sehr personalisiert und auf unser Projekt zugeschnitten war, was er ja auch sein muss.

Nachdem wir es geschafft hatten, dass der Computer ein Signal von dem Handy empfängt, machten wir uns an die Gestaltung des UI auf dem Handy. Für diese Aufgabe diente ein Programm, welches zu TouchOSC gehört, es heißt TouchOSC Editor. Mittels diesen Programms wurde nun das Umfeld geschaffen, welches die Bedienung des drinkBots ermöglicht. Dazu wurden erst einmal alle Elemente zusammen gesucht, welche wir für die Bedienung benötigen (Knopf, Schalter). Bis wir zu dem endgültigen Resultat gekommen sind wurden auch andere Möglichkeiten der Bedienung ausprobiert (z.B. Regler). Parallel zu dem UI auf dem Handy muss jedoch auch ein Fenster auf dem Computer offen sein, dessen Parameter in Processing definiert werden. Dieses parallel laufende Fenster kann jedoch sehr klein und unauffällig sein, sodass es nicht weiter stört.

Zu berücksichtigen bei der Kommunikation zwischen Handy und Computer ist, dass man nach jedem IP-Adressen Wechsel die Verbindung zwischen beiden Geräten über dieselbe erneut herstellen muss, da sich das Handy und der Computer über die IP-Adresse identifizieren.

Mathe

[Feven/Laurin/Conrad]

Mathe geht so: $a=x*b$

Mithilfe der Drehmatrizen und des Vektors der Kamera zum Mund errechnen wir einen Vektor vom Ursprung des Weltkoordinatensystems zum Mund. Dies geschieht durch das Multiplizieren des Vektors der Kamera mit den Drehmatrizen. Dann können wir mit dem errechnetem Vektor und der Jacobimatrix (welche von unseren zusammen multiplizierten Drehmatrizen abgeleitet wird) durch ein Annäherungsverfahren zur gewünschten Position der Endeffektors gelangen. Die Jacobimatrix gibt uns aus wie sich die Position des Endeffektors ändert durch bestimmten Winkeländerungen der verschiedenen Servos da sie die Ableitung der Drehmatrix von der Position des Endeffektors nach den Winkeln ist. Jedoch errechnet das Programm keine genauen Winkel sondern gibt uns nur Richtungen aus in die sich die verschiedenen Servos bewegen sollen. Der Servo dreht sich bei dieser Vorgehensweise immer wieder in die gewünschte Richtung bis der Endeffektor an seinem Ziel ankommt.

Bauteile

  • 3 Servos (Robotis Dynamixel AX-12)
  • ROBOTIS AX-12 / CDS55xx to Arduino Interface
  • Servo Netzteil
  • Webcam (Logitech HD Webcam C270)
  • Magnetventil
  • Arduino Nano & Breadboard
  • kleinere Schaltungsbausteine (Kabel, Widerstände, Mosfet, Diode)
  • Holz
    • Basisplatte
    • Verbindungsstücke
    • Krücke
  • Pappe
  • Silikonschlauch
  • Gummistopfen
  • Glasröhrchen

Was steckt wo drin?

  • Aufbau der Karosserie (Max)
    • Holz
      • Basisplatte
      • Verbindungsstücke
      • Krücke
    • Pappe
    • Silikonschlauch
    • Gummistopfen
    • Glasröhrchen
    • Magnetventil
  • Koordinaten bestimmen (Max)
    • Messen & Erkennung von x-& y-Koordinate
      • Webcam (Logitech HD Webcam C270)
      • Processing OpenCV
      • Gesichtserkennung
      • Munderkennung
    • Berechnung von z-Koordinate
      • Strahlensatz (Messungen –> Bild!)
      • Processing
  • Ansteuerung von Zielpunkt A
    • 3 Servos (Dynamixel AX-12)
  • Algorithmus zur Bewegung zum Punkt B
    • Vorwärts- und Inversekinematik

Pinbelegung

Pin Bauteil
D2 Servos (Rx)
D3 Servos (Tx)
D10 Magnetventil

Endstand des Projekts

  • Was leistet die entwickelte Lösung und woran scheitert sie?

So, nun kommen wir zu einem Fazit unseren Projekts. Was ist der Stand nach einem Semester? Viele Umstände sorgten für Verzögerung und erschwerten den gewünschten Fortschritt. So verkleinerte sich unsere Gruppe schnell, vorerst von 7 auf 4 Personen, später dann auf 3. Die zu erledigende Arbeit blieb jedoch gleich. Dies führte dazu, dass der Roboter nicht endgültig fertig wurde.

Obwohl die verbleibenden Projektmitglieder nun mehr als das doppelte der Arbeit zu erledigen hatten, erreichten wir dennoch nicht zu verachtende Ergebnisse. So kann der drinkBot den Mund erkennen, die x-, y- und z-Koordinate berechnen und diese Daten ausgeben. Was bisher nur in Ansätzen klappt, ist das Umwandeln dieser Koordinatendaten in die passenden Winkelgrößen für die Servos. Es ist dafür möglich den drinkBot in vorgegebene Servopositionen zu bringen sowie einzelne Servos anzusteuern. Der Roboter kann jedoch noch nicht selbständig den Weg zum Mund finden. Dafür ist es uns gelungen all die funktionierenden Steuerungen und Positionswechsel sowie das Ansteuern des Magnetventils auch über eine App auf einem Smartphone möglich zu machen. Es konnte also eine stabile Verbindung vom Smartphone über die laufenden Processing-Programme auf dem Computer bis zum Arduino hergestellt werden über die der Roboterarm bewegt werden kann.

Um eine funktionierende Umrechnung zu ermöglichen müssten die Munderkennung und die Mathe-Software besser kommunizieren. An diesem Punkt muss auch noch an der Übermittlung der Winkelwerte von Processing an den Arduino und der App-Steuerung gefeilt werden. Außerdem könnte das Hinzufügen einer Pumpe (z.B. eine Aquariumpumpe) das Upgrade auf eine neue Version (AQP1) mit sich bringen. Mit einer Pumpe könnte auf die Krücke und das Magnetventil verzichtet werden. Sie müsste genug Leistung liefern, damit das Getränk in den Mund gepumpt werden kann. Es würde die Größe des drinkBots verringern, die Transportfähigkeit und damit die Funktionalität verbessern.

Software & Quellcodes

Datenblatt Servos:
Servo-Arduino-Interface:
Schaltbild Magnetventil/Motor:
Arduino-Dynamixel (spanisch!!!):
TouchOSC:

lauffähige Versionen:

Kommunikation Processing (App) - Arduino:

mit Zahlen

mit Buchstaben

nicht ganz lauffähige Versionen:

Komplettpaket (Munderkennung, Koordinaten- & Winkelberechnung, Kommunikation mit Arduino)

abgeschlossene_projekte/drinkbot.txt · Zuletzt geändert: 2016/06/15 16:11 von c.jaedicke