pervasive logo
Motion Tracking


Technische Übersicht

Das Intersense IS-900 Tracking System liefert 6 Freiheitsgrade, basierend auf den Techniken der Trägheits- und Ultraschallsensoren. Die Positionierung und Orientierung der Tracker werden anhand von Accelerometern und Kompassdaten erkannt. Störungen werden durch einen erweiterten [ Kalman Filter ] mithilfe der Daten von den inertial Sensoren und der Ultraschallmessungen herausgefiltert. Das führt zu genauen und zitter freien 6-DOF (6 degree of freedom) Daten

Architektur

Die IS-900 Hardware besteht aus: SoniStrips™, den Trackern und der Prozess Einheit. Die SoniStrips™ übermitteln permanent 40 kHz Ultraschallsignale an den Tracker. Die inertial Komponente im Tracker errechnet und updatet immer wieder die Position und die Richtung. Die erhaltenen 6-DOF Daten werden von der IS-900 Prozess Einheit via RS-232 Verbindung an den Computer weitergeleitet.


(Bildquelle: http://www.isense.com/)

Vorraussetzung

Um Applikationen für das Motion Tracking System zu entwickeln sind folgende Punkte zu berücksichtigen: Die Intersense IS-900 Prozess Einheit muss eingeschaltet sein! Wenn diese ausgeschaltet ist an der Rückseite befindet sich der Power- Schalter! Der am Institut entwickelte Intersense Motion Tracking Netzwerkserver, (Näher zum Server siehe Einführung) muss laufen. Dieser Server ist auf dem Notebook installiert welches über die RS-232 Schnittstelle mit der IS-900 Prozess- Einheit verbunden ist. An dieses Notebook mit dem Benutzer "Pervasive" einloggen und die Verknüpfung "InterSenseServer" am Desktop starten. Die Tracker selbst über den Power- Schalter aktivieren. Es können maximal vier Tracker gleichzeitig betrieben werden.

Einführung

Der am Institut entwickelte Motion Tracking Netzwerkserver gibt die Möglichkeit beliebig viele Clients via TCP Socket Verbindung zu verbinden. Wobei jeder Client eine benutzerdefiniert Abfragegeschwindigkeit einstellen kann. Die höchst mögliche Datenabfragefrequenz beträgt 10ms. Die erhaltenen Datenpakete enthalten immer alle vier Trackerinformationen.

Der Motion Tracking Server

Um sich mit dem Server zu verbinden öffnet man eine Socket an die unter Serverdaten angegebene Adresse. Es empfiehlt sich den Socket im blocking Mode zu betreiben. dadurch vermeidet man etwaiges Polling. Jedes Datenpaket enthält immer vier Tracker 6-DOF Daten, egal ob dieser Tracker aktiv ist oder nicht (Näheres siehe Übertragungsprotokoll).

Der Server kennt zwei Datenübermittlungsmodus:
Rohdaten: X, Y, Z, heading, Neigung, Drehung
Whiteboard State Machine: X, Y, Zustand

Serverdaten:
IP Adresse: 140.78.95.180
Port: 7777

Das Übertragungsprotokoll

WICHTIG! Zur Interpretation der Koordinatendaten. Die erhaltenen float Zahlen bei X, Y und Z sind Werte in Meter. Die Neigungsgrade bei H, P und R bewegen sich zwischen 180 und -180 Grad.
X = Die Raumbreite, Y = Die Raumtiefe, Z = Die Raumhöhe
Beispiel:
X = 0, Y = 0, Z = 0; bedeutet links oben im Raumeck über den Türen
X = 7, Y = 7, Z = 3; bedeutet vorne (bei den Fenstern), rechts unten
	
--------------------------------------------------------------------------------------
Login vom Client zum Server (ASCII):


    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    1.) Anfordern der reinen Rohdaten (x, y, z, h, p, r) für die max. 4 Tracker
  
        ";;\n" 
        (wobei kind immer 1 für Rohdaten)

        Beispiel:
        "1;1000;\n"
        (Client möchte alle 1000ms Daten erhalten)


    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    2.) Anfordern der Zeichenpixel und der Zeichenzustände

        ";;;;\n"
        (wobei kind immer 2 für Zeichenpixel)

        Beispiel:
        "2;500;1024;768;\n"





---------------------------------------------------------------------------------------
Antwort vom Server zum Client (Binär):


    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - -
    1.) Senden der Rohdaten

        4 Bytes  (long)  len          Anzahl der Messungen (wobei 1 Messung 96 Bytes hat)

        4 Bytes  (float) x            +                          +
        4 Bytes  (float) y            |                          |
        4 Bytes  (float) z            |  24 Bytes (Tracker 0)    |
        4 Bytes  (float) heading      |                          |
        4 Bytes  (float) pitch        |                          |
        4 Bytes  (float) roll         +                          |
                                                                 |
        4 Bytes  (float) x            +                          |
        4 Bytes  (float) y            |                          |
        4 Bytes  (float) z            |  24 Bytes (Tracker 1)    |
        4 Bytes  (float) heading      |                          |
        4 Bytes  (float) pitch        |                          |
        4 Bytes  (float) roll         +                          |
                                                                 |  96 Bytes pro Messung
        4 Bytes  (float) x            +                          |
        4 Bytes  (float) y            |                          |
        4 Bytes  (float) z            |  24 Bytes (Tracker 2)    |
        4 Bytes  (float) heading      |                          |
        4 Bytes  (float) pitch        |                          |
        4 Bytes  (float) roll         +                          |
                                                                 |
        4 Bytes  (float) x            +                          |
        4 Bytes  (float) y            |                          |
        4 Bytes  (float) z            |  24 Bytes (Tracker 3)    |
        4 Bytes  (float) heading      |                          |
        4 Bytes  (float) pitch        |                          |
        4 Bytes  (float) roll         +                          +

        ... (insgesamt len * 96 Bytes Daten)
           
        1 Byte   (char)  \n
        


    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - -
    1.) Senden der Zeichenpixel

        4 Bytes  (long)  len          Anzahl der Messungen (wobei 1 Messung 48 Bytes hat)

        4 Bytes  (long)  x            +                          +
        4 Bytes  (long)  y            |  12 Bytes (Tracker 0)    |
        4 Bytes  (long)  state        +                          |
                                                                 |
        4 Bytes  (long)  x            +                          |
        4 Bytes  (long)  y            |  12 Bytes (Tracker 1)    |
        4 Bytes  (long)  state        +                          |
                                                                 |  48 Bytes pro Messung
        4 Bytes  (long)  x            +                          |
        4 Bytes  (long)  y            |  12 Bytes (Tracker 2)    |
        4 Bytes  (long)  state        +                          |
                                                                 |
        4 Bytes  (long)  x            +                          |
        4 Bytes  (long)  y            |  12 Bytes (Tracker 3)    |
        4 Bytes  (long)  state        +                          +
                                                                 
        ... (insgesamt len * 48 Bytes Daten)
           
        1 Byte   (char)  \n


        wobei state:
        0: idle
        1: pointing
        2: draw
        3: erase
        4: clearall
	

Code Beispiel in C++

In diesem Beispiel werden die reinen Rohdaten (6-DOF) vom Server abgerufen

#include "ClientSocket.h"
#include "SocketException.h"

using namespace std;

int main(int argc, char *argv[])
{
  list<int> mylist;
  list<float> mylist2;
  list<float>::iterator iter;
  char byte;
  int length; 
  int newline;

  try

    {
      ClientSocket client_socket ( "140.78.95.180", 7777 );

      try
	{

	  client_socket << "1;1000;\n";

	  while(1) 
	  {
		client_socket.recv_int(mylist,1);
		length = mylist.back();
	  	mylist.pop_front();

		client_socket.recv_float(mylist2,24 * length);
		cout << "Float List size:" << mylist2.size() << endl;		

		iter = mylist2.begin();
		newline = 1;		

		while(iter != mylist2.end()) 
		{
			cout <<	" " << *iter;	
			if(newline % 6 == 0)
				cout << endl;
			iter++;
			newline++;
		}

		mylist2.clear();
          	client_socket.one_byte(byte);
		cout << endl;
	  }

	}
      catch ( SocketException& ) {}


    }
  catch ( SocketException& e )
    {
      cout << "Exception was caught:" << e.description() << "\n";
    }

  return EXIT_SUCCESS;
}


Code Beispiel in Perl

In diesem Beispiel werden die Zeichenpixel und Zeichenzustände vom Server abgerufen

sub ISopen ($$$$$) {
	my ($host, $port, $reqTime, $width, $height) = @_;

	$requestTime = $reqTime;
	$dataReadEnd = 0;
	$threadRun = 1;

	openSocket($host, $port);
	sendMsg("2;$reqTime;$width;$height;\n");
	$typeglob = getHandler();

	$thread  = threads->new(\&ISstart);
}


sub ISstart {
	

	while(1) {

		if($dataReadEnd == 1) {
                        warn "exit thread!\n";
			close $typeglob;
                        last;
                }


		read($typeglob,$buffer,4);
		$bufferLength = unpack("i",$buffer);

	 	for(my $a = 0; $a < ( 4 * $bufferLength ); $a++) {
			read($typeglob,$buffer,12);

			my ($x,$y,$t) = unpack("i i i",$buffer); 

			
			$DataQueue->enqueue($x, $y, $t);
		}

		read($typeglob,$buffer,1);


		if( $DataQueue->pending > $maxQueueSize ) {
			warn "ISstart: Thread die cause buffer > $maxQueueSize !\n\n";
			last;
		}
	}

}


OpenGL Pervasive Lab

Tracking im OpenGL Raummodel


In einem 3D Raummodel werden die Tracker sichtbar gemacht. Es wird sowohl die Position 1:1 dargestellt als auch die Ausrichtung. Es lassen sich die Rohdaten einblenden. Durch die gesamte Szene kann man sich in zwei verschiedenen Modi bewegen, im "Walk" bzw. im "Fly" Modus.

GL Pervasive Lab [more]

Download

Perl Beispiel [tar.gz] [zip]
C++ Beispiel für Linux [tar.gz] [zip]

TODOs

  • Motion Recorder:
    Aufzeichnung von Bewegungsabläufe unabhängig vom Ursprung im Raum mit einem Eingabeinterface welches eine Zuordnung zu einer Aktion bereitstellt, welche Ausgeführt werden soll wenn das Ereignis eintritt. D.h. Das Aufrufen einer Socketverbindung oder das Ausführen einer Datei.
  • Joystick Treiber für Linux:
    Zur Steuerung von 3D - Applikation im Pervasive Lab

Autor

Bei Fragen oder sonstigen Anregungen bitte Mail an: Dominik Hochreiter