KinectHeli

Aus toolbox_interaktion
Wechseln zu: Navigation, Suche

Ein Projekt, bei dem ein ferngesteuerter IR - Helikopter durch Gesten die mit der Kinect  aufgenommen wurden gesteuert werden kann.


Einführung und Motivation

Da konventionelle Steuerungsmethoden für  ferngesteuerte Helikopter nach eigenen Erfahrungen weder intuitiv funktionieren noch sehr spaßig  sind, haben wir uns auf die Suche nach modernen, intuitiven und außergewöhnlichen Steuerungsmethoden gemacht.

Da die Möglichkeiten der Microsoft Kinect uns am meisten beeindruckt haben, werden die Handgesten, mit denen der  Helikopter später gesteuert werden soll, mit dieser aufgenommen.

Die Weitervearbeitung der durch die Kinect gewonnenen Daten wird mithilfe der Kinect SDK am PC vorgenommen.

Für die Übertragung der Infrarot Signale haben wir uns für das Arduino Uno mit einer extern angeschlossenen Infrarot-Sendediodenschaltung entschieden.

Umsetzung

Grundgedanke

IrHeli-Aufbau.png


Mithilfe der in der Kinect SDK enthaltenen Objekte ist eine genaue Positionsbestimmung von verschiedenen Punkten am menschlichen Körper sowie deren selektierung möglich.


Dadurch ist eine Umrechnung der von der Kinect gelieferten Daten in die für die Steuerung des Helikopters benötigten Werte leicht umzusetzen. Diese Werte werden mithilfe von OSC an einen weiteren Laptop übermittelt, welcher die erhaltenen Daten an den Arduino weiterleitet.

Der  Arduino übermittelt die erhaltenen Werte mithilfe der angeschlossene IR-Diode  an den Helikopter.



Komponenten

Syma S107

RC-helicopter-start.png.jpg
  • Günstige Anschaffung ( < 50€)
  • Bekanntes IR-Protokoll
  • Laden über Fernbedienung oder PC (USB)
  • Aufgrund des Preises kurze Akkulaufzeit und lange Ladezeiten

Weiterführende Informationen:
- http://www.symatoys.com/product/show/1856.html

Kinect

Kinect Desc.png
  • Hardware zur Steuerung von Videospielen der Xbox 360
  • Bedienung der Software durch Körperbewegungen
  • die Steuerung wird durch eine Kombination von PrimeSense-Tiefensensor, 3D-Mikrofon, Farbkamera und Software ermöglicht
  • außerdem ist eine Sprachsteuerung möglich
  • angeschlossen wird die Kinect mit einem üblichen USB Stecker


Weiterführende Informationen:
- http://de.wikipedia.org/wiki/Kinect
- http://www.xbox.com/de-DE/Kinect


Arduino Uno

Arduino-uno-perspective-transparent.png
  • Einfache Programmierung
  • Günstig
  • Im Labor vorhanden
  • Kommunikation mit Arduino über eine über USB simulierte serielle Schnittstelle


Weiterführende Informationen:
- http://en.wikipedia.org/wiki/Arduino


Programm (Code) & Schnittstellen

OSC Nachrichten

OSC-Schnittstelle


In diesem Fall wird OSC verwendet, um die drei Werte an einen Laptop, der mit dem Arduino verbunden ist, weiterzusenden. Die Nachricht besteht aus einer Adresse, in diesem Fall „/gso/interaktion/irheli/xyz“, den drei ermittelten Werten und der Zeit. Die Werte werden an die Adresse angehängt: Erst der Wert für die Drehung, danach der Wert für die Vorwärts- und Rückwärtsbewegung und als letztes der Wert für die Höhe. Dahinter wird noch ein Zeitstempel angehängt. Im folgendem Code - Ausschnitt ist die OSC Sendefunktion dargestellt.

IrHeli - OSC Sende Code.png


USB Kommunikation

Die direkte Verbindung des PCs oder Laptops, auf dem die Applikation läuft, sowohl mit der Kinect als auch mit dem Arduino hatte den großen Vorteil, dass sie unabhängig vom Netzwerk ist und somit auch unabhängig von eventuellen Störungen, die dort auftreten können. Zudem wurde durch die Reduzierung auf ein System nicht nur die Schnelligkeit erhöht, sondern auch die Fehleranfälligkeit reduziert. Um die Daten direkt über USB an den Arduino zu senden, wird die SerialPort Klasse aus dem .NET Framework verwendet.

   private void sendUSB(byte[] buf, int len)
    {
            if (_sport == null){
			init_sp();
	    }
	    if (_sport == null) {
			return;
            }
	    try {
	                _sport.Write(buf, 0, len);
	    }
	    catch {
			_sport.Close();
			_sport = null;
            }
    }



Arduino Code

Irheli-Flussdiagramm.png

In der nebenstehenden Abbildung ist der Ablauf des Arduino - Codes visualisiert.

Der Code besteht, Arduino typisch, im wesentlichen aus zwei Funktionen. Die erste Methode ist void setup(). Hier werden Grundeinstellungen vorgenommen (z.B. ob ein Kanal ein In- oder Output ist). Diese Methode wird nur beim Programmstart ausgeführt. Die void loop() Methode wird im Gegensatz zum Setup ständig wiederholt. Hier wird der eigentliche Programmablauf geschrieben. In unserem Fall befinden sich hier mehrere if() - Abfragen. Hieraus wird desweiteren die Methode IR_OutPulse aufgerufen. Sie dient zur Einhaltung der vorgegebenen 38kHz Taktung. Für weitere Informationen wird auf die Datei:Http://www.interaction-toolbox.de/ weiter/weiterleiten.php?link=anwendungen/KinectHeli/Projektarbeit.pdfverwiesen (Kapitel 4.2).

void IR_OutPulse (int Pulse) {  //sends 38Khz pulses over the Pulse Length
	int p;
 
	for (p = 0; p < (Pulse / 26) - 1; p++) {  //Takes about 26 microseconds per loop
		digitalWrite(PIN_IR, HIGH);
		delayMicroseconds(10);
 
		digitalWrite(PIN_IR, LOW);
		delayMicroseconds(10);
        }
}

Infrarot Protokoll

IrHeli-signaltiming.png

Bei dem Infrarot Protokoll handelt es sich um ein einfaches auf 38 KHz moduliertes Signal, welches in kurzen Intervallen jeweils 4 Bytes überträgt.

Das Signal beginnt mit dem Infrarot Protokoll spezifischen Header. Danach folgen die vier Bytes für die Störung, deren Bedeutung im folgenden kurz erläutert wird:

  1. links/rechts
  2. vorwärts/rückwerts
  3. Höhe
  4. unbedeutend / unbekannt (nicht benötigt)

Ein Byte kann dabei Werte von 0-127 (Kanal A) oder 128-255 (Kanal B) annehmen, wobei dabei jeweils 63/191 der Mitte(außer bei der Höhe) entspricht.

Für die spezifische Analyse des Infrarot Protokolls wird auf die Ausarbeitung der Projektarbeit (Kapitel 4.1) verwiesen.


C# Code für die Selektierung

switch (joint.JointType)
{
   case JointType.HipCenter:
   {
      HipCenter.X = joint.Position.X;
      HipCenter.Y = joint.Position.Y;
      HipCenter.Z = joint.Position.Z;
   }
   case JointType.Head:
   {
      Head.X = joint.Position.X;
      Head.Y = joint.Position.Y;
      Head.Z = joint.Position.Z;
   }
   default:
      break;
}


Einfaches Code-Beispiel für die Selektierung der Hüft- und Kopfposition.

Steuerungsbewegungen

Die Umsetzung der Steuerung bedurfte etwas Erfindungsreichtum. Da nur zwei Hände zur Verfügung stehen, um einen drei–kanaligen Helikopter zu steuern, mussten Bewegungen festgelegt werden, die der Nutzer ausführen sollte.

Da vermehrt Kritik an unserer Umsetzung geäußert wurde, soll hier nicht näher auf unseren Lösungsweg eingegangen werden.

Bei Interesse ist unsere Lösung in der Projektausarbeitung zu finden.

Probleme

  • Anfängliche Versuche zur Weitervarbeitung der Kinectdaten mit EyesWeb sind gescheitert
  • Fehlende Feinabstimmung der Datenrate über OSC
  • Zu starke Schwankung der aufgenommenen Daten -> Regelung notwendig
  • ergonomische Steuerbewegungen finden

Ausblick

Die Lange Nacht der Wissenschaften - Samstag 19.10.2013 - 18-1 Uhr Raum: WE.206

Es wäre denkbar, die Kinect als Eingabegerät z.B. durch ein Smartphone zu ersetzen. Durch den modularen Aufbau ist eine einfache Trennung bzw. Ersetzen der Geräte möglich.