Beschleunigungsvektor in Weg eines gek. Systems

Liebe/-r Experte/-in,

unter http://www.youtube.com/watch?v=XwwJkF9KDOA findest du ein Video.
Dieses zeigt symbolhaft ein Mobiltelefon, das am Hinterkopf eines
Menschen angebracht ist. Die weißen Kugeln symbolisieren die Augen,
Drehung geschieht um den Hals in den Freiheitsgraden, die ein Kopf hat.

Das Display des Mobiltelefones zeigt nach außen. Es hat einen
Schwerkraftkompensierten 3D-Beschleunigungssensor. Das heißt, wird der
Kopf beschleunigt, wird auch das Mobiltelefon beschleunigt, und - nicht
vergessen - negativ beschleunigt beim Abbremsen.

Wie es bei Headtrackern so ist, soll die Bewegung auf Mausbewegung
umgelenkt werden. Das ist soweit kein Problem. Auch die Daten vom Handy
zu gewinnen ist kein Problem.

Nein, es ist ein Logikproblem, aus den X, Y und Z-Komponenten der
Beschleunigung(siehe http://developer.android.com/images/axis_device.png
) relative Mausbewegungen abzuleiten.

Die Frage ist konkret: Wie muß - bei den im Video gezeigten
Bewegungen(merke, das Mobiltelefon ist gekippt) - eine Funktion
X_Maus_relativ = f(X_Handy,Y_Handy,Z_Handy) und Y_Maus_relativ =
f(X_Handy,Y_Handy,Z_Handy) aussehen?

Meine Ideen:
Weg_Vektor = Beschleunigung_Vektor * (Zeit)².

Weg_x = Beschleunigung_x * (Zeit)²
Weg_y = Beschleunigung_y * (Zeit)²
Weg_z = Beschleunigung_z * (Zeit)²

Meine Ideen:
Weg_Vektor = Beschleunigung_Vektor * (Zeit)².

hi,

die Formel gilt nur für konstante Beschleunigung. Außerdem heißt sie korrket:

s = 0,5*a*t^2+ v*t

Mit der Schulphysik wirst du hier nicht weiter kommen. Vielmehr solltest du die empfangenen Daten in einem Array verarbeiten und dir schrittweise die Geschwindigkeit und Beschleunigung errechnen.
Die Kippung kannst du mit Trigonometrie sin, cos und tan rausrechnen.
Was für Bewegungen willst du mit der Maus aufzeichnen. Nur die Bewegung in der x-z-Ebene? Dann kannst du die y-Koordinate vernachlässigen.

Was für Bewegungen willst du mit der Maus aufzeichnen. Nur die
Bewegung in der x-z-Ebene? Dann kannst du die y-Koordinate
vernachlässigen.

Nun ich will den Headtracker an einem VR-Helm befestigen, damit ich mich in Spielen „umschauen“ kann. Bei Spielen wird die Bewegung der Maus auf eine Kugelinnenseite übertragen. Ich dachte also daran, mit Kugelkoordinaten zu hantieren.

Ich erhalte vom Handy folgende Werte:
X_Wert_Beschleunigung;Y_Wert_Beschleunigung;Z_Wert_Beschleunigung, also zum Beispiel 1,2;-2;1 und das circa alle 0,3 Sekunden neu.

Wie nutze ich diese Daten mit deiner Formel?

Was verstehst du unter „Vielmehr solltest du die empfangenen Daten in einem Array verarbeiten und dir schrittweise die Geschwindigkeit und Beschleunigung errechnen.“?

Zur Kippung: Welches Koordinatensystem siehst du als Referenz, also zu welchen Achsen willst du die sin/cos/tan Beziehungen setzen?

Letztlich bewegt sich das Handy auf einem Kugelmantel, allerdings kann ich die z-Komponente(http://developer.android.com/images/axis_device.png) nicht vernachlässigen, da es wie gesagt nicht anliegt bzw. die x & y-achse keine Tangenten der Kugel sind, auf deren Mantel sich das Handy bewegt.

Hallo,

ich habe zurzeit keine Zeit mich wirklich in Deine Frage reinzudenken.

Ich komme frühestens Anfang nächster Woche dazu.

Tut mir Leid.

Gruß Volker

Danke für deine ehrliche Rückmeldung. Ich freue mich auf deine Antwort.

Hallo,

Die Formel
Ort = Beschleunigung * Zeit^2
gilt nur für gleichförmig beschleunigte Systeme (zB freier Fall) ohne Anfangsort und -geschwindigkeit.

Für alle anderen Systeme muss die Beschleunigung a(t) nach der Zeit integriert werden. Dazu verwendet man am besten den Ort x(t) und die Geschwindigkeit v(t) als unabhängige Variablen und schreibt die Ableitungen (x,v und a sollen Vektoren sein):
d/dt x(t) = v(t)
d/dt v(t) = a(t)
Dies ist ein System von gewöhnlichen Differentialgleichungen erster Ordnung (und damit ein mathematisches Problem, welches mit Sicherheit nicht jeder Maturant/Abiturient schon mal gesehen geschweige denn gelöst hat; also etwas schwierig zu lösen).

In deinem Fall wird es sich um eine numerische Integration handeln, also gilt in erster Näherung (Achtung: dient hier nur der Veranschaulichung und darf in dieser Form nicht verwendet werden, siehe unten!):
x(t0 + dt) = x(t0) + v(t0) dt
v(t0 + dt) = v(t0) + a(t0) dt
Hier ist t0 die aktuelle Zeit, x(t0) der aktuelle Ort, v(t0) die aktuelle Geschwindigkeit, a(t0) die aktuelle Beschleunigung und dt das Zeitintervall zwischen den Ausgabewerten des Beschleunigungssensors.

(Falls du damit nicht vertraut bist: die beiden Zeilen oben beschreiben, wie ausgehend von einem Zeitpunkt t0, an dem x und v bekannt sind, x und v prinzipiell zu einem späteren Zeitpunkt t0+dt berechnet werden können. Dann nimmt man die berechneten Werte wieder als Startwerte und kommt auf x und v zum Zeitpunkt t0+2dt, danach bei t0+3dt usw.)

ACHTUNG:
Dies gilt nur in erster Näherung, erzeugt schlechte Ergebnisse und darf in dieser Form nicht angewendet werden!!! Für die numerische Integration gibt es spezielle Verfahren (siehe zB Runge-Kutta), die robust sind und gut konvergieren. Die Grundidee ist aber die gleiche: aus x(t0) und v(t0) über die Beschleunigung a(t0) den Ort und die Geschwindigkeit zum Zeitpunkt t0+dt berechnen, nur verwendet man Zwischenschritte.
Es gibt mit Sicherheit einige gute Anleitungen im Netz zum 4-stufigen Runge-Kutta-Verfahren, es ist ein klassisches Standardverfahren.

Zum Abschluss noch: Wenn die Bahn x(t) für alle Zeitpunkte berechnet ist, gilt diese im Koordinatensystem des Beschleunigungssensors. Wie man beim Headtracking üblicherweise aus der 3D-Bahn eine 2D-Bahn für die Maus macht, weiss ich leider nicht.

Ich hoffe, ich konnte helfen.
Bei Fragen bitte melden.
SG

Hallo donathus.orth,

zu Deiner Anfrage fallen mir zwei Punkte ein.

  1. Es gibt möglicherweise ein kleineres Problem bei der Betrachtung der Bewegungen. Der Mauszeiger soll sich auf einer Ebene bewegen. Diese Bewegungsform nennt man eine Translationsbewegung, eine Verschiebungsbewegung also.

Jetzt ist die Kopfbewegung nach links oder rechts aber eine Rotationsbewegung. Natürlich gibt es auch hier eine Winkelbeschleunigung, die man in eine Translationsbeschleunigung des Mauszeigers übersetzen kann.

In einfachen Worten: Um den Mauszeiger so zu steuern wie er sich über den Bildschirm bewegt, müsste man eigentlich den Kopf gerade halten und dann den ganzen Körper nach links/rechts oder oben/unten verschieben.

Das tun wir aber nicht, sondern wir drehen eben den Kopf, d.h. es erfolgt eine Beschleunigung nicht nur entlang einer, sondern entlang von zwei Raumachsen. Wenn man z.B. den Kopf nach links dreht, dann erfolgt eine Beschleunigung in x- UND in -z -Richtung entsprechend den Koordinatenachsen im Bild.

Das ist möglicherweise unkritisch, da wir bei einer leichten bis mittleren Kopfdrehung nach rechts/links größere Beschleunigungswerte entlang der x- als entlang der z-Achse haben.
Möglicherweise kann diese vereinfachte Betrachtungsweise aber auch Ursache für „Übersetzungsfehler“ in die Mausbewegung sein.
Vor allem bei Positionen am Bildschirmrand müssten diese dann auftreten

  1. Die Formeln für die Beschleunigung stimmen, wenn man davon ausgeht, dass man eine GLEICHMÄßIGE Beschleunigung aus dem Stand ausführt.
    Die Kopfbewegungen sind aber alles andere als gleichmäßig.

Lösen lässt sich das Problem, indem man die Bewegung in kleine Zeitschritte (Delta t) unterteilt, z.B. die Ausleseintervalle des Sensors. Für jeden Zeitschritt kann man nun den zurückgelegten Weg innerhalb dieses Zeitschritts nach der Formel unten bestimmen:

Während Delta t zurückgelegter Weg = 1/2*a*(Delta t)^2+v_0*Delta t

a = aktuelle Beschleunigung in diesem Zeitintervall (diese ändert sich von Intervall zu Intervall)
v_0 = Anfangsgeschwindigkeit, zu Beginn des Zeitschritts (macht ja einen Unterschied im zurückgelegten Weg, wenn man schon 120 km/h fährt und dann etwas beschleunigt, wie wenn man die gleiche Beschleunigung aus dem Stand macht)

v_0 bekommt man so: Beschleunigung im Zeitfenster vorher mal die Dauer des Zeitfensters plus die Geschwindigkeit, die man aus dem Zeitfenster da davor hatte.

v_0=a_vorher*Delta t_vorher+v_vorhervorher

Delta t ist normalerweise konstant, v_vorhervorher muss bekannt sein, d.h. es muss an einem ein Startpunkt klar sein, ab dem man davon ausgehen kann, dass v_ganzamaanfang = 0 war.

Dies lässt sich am einfachsten dadurch realisieren, indem man über mehrere Intervalle die aktuelle Beschleunigung ausliest. Ist diese Null, dann bewegt sich der Kopf auch nicht mehr, da die Kopfbewegungen meist kurze beschleunigte Bewegungen sind und ansonsten keine Bewegung auftritt.

Ich hoffe, ich konnte Dir mit der Antwort weiterhelfen. Melde Dich einfach, wenn Du noch Fragen haben solltest. Z.B. auch, wenn die Rotation in der Bewegungserfassung eine Rolle spielen soll.

Würde mich auch echt interessieren, wie´s weitergeht.

Schöne Grüße und gutes Gelingen,

Daniel

P.S.:
Ach so, ja, noch ein letzter Punkt. Das ganze Tracking funktioniert nur fehlerfrei, wenn der Getrackte an einem Ort sitzt. Viel schwieriger wird´s dann, wenn er sich in einem bewegenden Fahrzeug aufhält.

Hallo. Mir gefällt deine Antwort.

Leider kann ich mein Problem nicht in Verbindung zum RungeKutta-Verfahren bringen. Dort wird mit Funktionen hantiert. Ich habe keine Funktion, ich habe diskrete Werte für die Beschleunigung. Ich habe eine RK-Implementierung unter http://csharpcomputing.com/tutorials/Lesson16.htm gefunden. Mir ist unklar, was mir

a) dieser Algorithmus für mein Problem nutzt
b) die Bahn x(t) für alle Zeitpunkte nutzt

Vieleicht nochmal in anderen Worten was ich machen möchte:

Ich habe also alle 0,3 Sekunden einen String der da lautet:
X_Beschleunigung_Handy;Y_Beschleunigung_Handy;Z_Beschleunigung_Handy.

Zum Beispiel:

1;-2;4
0;2;0
0;-2;2

Ich teile den String und habe

Besch[0]
Besch[1]
Besch[2]

Jetzt kann ich noch die Zeit zwischen zwei Meßwerten messen und habe damit ein dt.

Das ist alles. Ich kann zum Eichen den Kopf stillhalten und dies als Koordinatenursprung definieren aber mehr habe ich nicht.

Letztlich ist mein Ziel, die Geometrie der Anordnung einbeziehend, den Unterschied im Weg zwischen Messung(t0) und Messung(to+dt), also der nächsten Messung, in die X und Y-Komponenten der Wege auf dem Kugelmantel, den ich „sehe“ zu übertragen. Der Kugelmantel ist definiert durch einen imaginären Punkt, der auf einer Normalen durch die Augen in konstantem Abstand ist. Drehst du den Kopf in allen erdenklichen Neigungswinkeln und Drehungswinkeln, solltest du in etwa eine Halbkugelinnenseite oder eine vergleichbare geometrische Figur beschreiben.

Danke im Voraus

donatus

Hallo. Mir gefällt deine Antwort.

„Das ist möglicherweise unkritisch, da wir bei einer leichten bis mittleren Kopfdrehung nach rechts/links größere Beschleunigungswerte entlang der x- als entlang der z-Achse haben.“

Ich möchte das miteinbeziehen. Alleine schon deshalb, weil wegen der minimalen Drehung und Kippung des Handys die X-Richtung des Handys nicht die X-Richtung des Kopfes ist.

Der Headtracker ist für einen VR-Helm mit eigenen Monitoren. Die Mausbewegung soll nicht auf den Monitor im Sinne von Mauszeigerbewegungen sondern in Form von Drehungen einer Spielfigur, also der Perspektive, in einem 3D-Spiel übertragen werden.

Unabhängig von der Geometrie kam ich mit deinen Formeln auf http://pastebin.com/B2yzwyiP , ist es das, was du meinst?

Ich glaube nicht, dass das allein mit einem Beschleunigungssensor so möglich ist, wie du dir das vorstellst.

Anhand der Beschleunigung kannst du ja erst durch zweimalige Integration auf den Weg kommen. Das ist numerisch sehr ungenau - ein kleiner Fehler und die Geschwindigkeit wird nie wieder Null und du erreichst nie wieder die Ruhelage. Um zu testen, ob das trotzdem funktioniert, würde ich das Handy erstmal nur ein Stück um eine (fest definierte) Achse hin- und herbewegen und den Weg integrieren. Ich wage allerdings zu bezweifeln, dass du danach wieder am Ausgangspunkt landest.

Wie wölltest du anhand der Beschleunigung feststellen, ob sich dein Kopf dreht oder sich vielleicht seitlich bewegt? Insgesamt gibt es ja 6 Freiheitsgrade - 3 räumliche Bewegungen und 3 Drehungen.

Genau genommen bewegst du deinen Kopf ja um den Hals. Diese Bewegung lässt sich definitiv nicht als Bewegung um irgend einen Punkt im Raum interpretieren, insbesondere nicht um einen Mittelpunkt im Kopf. Mathematisch wäre das sehr schwer zu beschreiben - und könnte höchsten experimentell bestimmt werden.

Wenn du stattdessen Lagesensor (Neigung des Kopfes) und Kompass (Blickrichtung) zur Verfügung hättest, könnte ich mir schon eher vorstellen, dass du dein Vorhaben umzusetzen könntest.

Alex

Wenn du stattdessen Lagesensor (Neigung des Kopfes) und
Kompass (Blickrichtung) zur Verfügung hättest, könnte ich mir
schon eher vorstellen, dass du dein Vorhaben umzusetzen
könntest.

Die habe ich zur Verfügung. Allerdings ist dieser Sensor einerseits langsam und andererseits stößt er auf Probleme wenn die Neigung von flachem Handy zu Vertikalem Handy sich ändert, denn dann gibt der Kompaß nicht mehr die richtige Position aus. Hast du etwas ähnliches bereits getan? Das Beschreiben des Fehlers mit dem Kompaß ist schwer, hast du es bereits gesehen wüßtest du was ich meine.

Ich kenne mich mit den Sensoren nicht wirklich aus - mein Handy hat nichts dergleichen …

Obwohl ich mir das mit dem Kompass-Sensor vielleicht so wie bei einem klassischen Kompass vorstellen könnte. Wenn du den schräg hältst, dann wirds ungenau.

Aber im moment fällt mir keine wirklich gute Alternative ein. (Wie wird es denn bei einem VR-Helm gemacht?)

Alex

Da hast Du Dir etwas vorgenommen. Zunächst, wenn ich die Aufgabe richtig verstehe, ist sie unlösbar. Ein starrer Körper hat 6 Freiheitsgrade und Du misst nur 3 Parameter. Das System ist also unterbestimmt.

Lösen kannst Du es mit Annahmen. Du kannst z.B. annehmen, dass der Kopf starr auf dem Hals sitzt. Dann reduziert sich das Problem auf eine Transformation mit einer Drehmatrix.

In dem Video sehe ich eigentlich nur Drehungen des Kopfes, keine linearen Bewegungen. Das kannst Du exakt nicht mit einem Beschleunigungssensor aufnehmen; allenfalls mit zweien an verschiedenen Stellen, die fest zueinander orientiert sind.

Wenn Du natürlich weißt, dass es nur Drehungen des Kopfes gibt und eben keine Bewegungen des ganzen Menschen, kannst Du versuchen Annahmen über die Drehachsen zu treffen. Bei Oberarm und Oberschenkel kann das funktionieren, beim Kopf i.A. nicht. Kleine Gierbewegungen lassen sich wohl noch auf dem Axis verorten, nicken und rollen haben wohl positionsabhängige Achsen, die zu allem Überfluss noch von persönlichen Gewohnheiten abhängen.

Also, Physik hilft hier nur begrenzt. Ob es eine geeignete Heuristik gibt, ist schwer zu sagen.

Grüße,

  • lars.

„Dann reduziert sich das Problem auf eine Transformation mit einer Drehmatrix.“
Wie sieht die hier aus?

Grüße

Hi,

der Code sieht - soweit ich das überblicken kann - gut aus. Die Variablen weg_x, weg_y und weg_z geben aber nur den in dt zurückgelegten Weg an. Sie entsprechen nicht der Gesamtstrecke von Anfang an. Dazu müsste dann zu jedem weg_x noch jeweils der weg_x aus der vorherigen time bin dazuaddiert werden.

Ich habe noch eine Verständnisfrage:
Sollen die Trackingdaten dazu dienen, die Blickrichtung des Spielers im virtuellen Raum festzulegen? Also so ähnlich wie in der Animation?
Oder soll mit den Kopfbewegungen ein anderes Objekt angesteuert werden, dass der Betrachter sich bewegen
sieht?

Falls ersteres der Fall ist, benötige ich noch ein wenig Zeit, um das Ganze durchzurechnen.
Ich würde dann einen Zusammenhang herstellen zwischen der Kopfhaltung und der Ebene, die durch die optischen Achsen der Augen geht.
D.h. man hätte dann zwei Koordinatensysteme, die man miteinander verknüpfen müsste.
KS 1 das Handysystem, das die Daten erzeugt, das aber im Raum bewegt wird. Im ersten Anlauf würde ich zunächst von einem nicht verkippten Handy, das am Hinterkopf befestigt ist, ausgehen. Später lässt sich die Verkippung noch als eine Konstante in jeder Raumrichtung dazuaddieren.
KS 2 das raumfeste „Kopfsystem“. Die Position des Handys muss dann bezüglich diesem System festgestellt werden. Daraus lässt sich dann die Lage der Augenhorizontebene und daraus dann die Blickrichtung ableiten.

Noch eine Frage zur Schwerkraftkompensation. Wird die Erdbeschleunigung „von Hand“ aus den Daten herausgerechnet oder macht das schon der Sensor im Handy? Möglicherweise könnte man nämlich die Lagebestimmung durch das Auslesen der Richtung der Erdbeschleunigung vereinfachen.

Schöne Grüße,

Daniel

Wenn ich das richtig verstehe, geht es um die Richtung, in die der Kopf zu den verschiedenen Zeitpunkten schaut, oder?

Stimmt das folgende?
Am Anfang ist das Handy in Ruhe, hängt aber schräg. Diese Anfangsposition entspricht zB „gerade aus“. Also nehmen wir für die Anfangsmausposition den Ursprung.

Wenn das Handy aus diesem Anfangszustand zB um ein Grad nach rechts gekippt wird, soll die entsprechende Mausposition etwas rechts vom Ursprung sein.

Kippt es danach noch weiter nach rechts, soll die Maus ebenfalls noch weiter nach rechts gehen. Kippt es nach links/oben/unten, sollte die Maus nach links/oben/unten folgen usw.

Die Maus soll also der Richtung des Handys folgen? Hab ich das richtig verstanden?

Misst das Handy die Beschleunigung in Relation zur Erdanziehung?
Soll der Helm nur die Rotation deines Kopfes erfassen, oder möchtest du dich mit dem Helm bewegen?

In jedem Fall brauchst du eine Referenz zu den Beschleunigungsachsen, da deine Messung sonst „in der Luft hängt“.

Mal einen imaginären Ablauf der Nutzung:
Du startest mit deinem Helm und initialisierst die Startposition als Nullpunkt (Koordinatenursprung).
Dann musst du aus der Beschleunigung und den 0.3s (könnte knapp werden) den Ort - also den Vektor zum Ursprung - herausrechnen.
Diese Rotation/Bewegung setzt dir dann irgendein System (Hardware oder Software?) in Mauskoordinaten um.

Problem bei der Berechnung:
Du kannst für die Bewegungen keine konstante Beschleunigung annehmen.
Es gibt für den Fall also keine 0815-Formeln. Jedoch kannst du die Daten in kleine Zeitabschnitte quanteln und für jede dieser kleinen Zeiteinheiten konstante Beschleunigung annehmen, da in 1 ms nicht grad die größte Beschleunigungsänderung passiert. Ob hier die 0,3s reichen kann ich nicht sagen. Die Aktualisierungsrate deiner Kopfrotation beträgt dann eben auch 0,3s. Wenn man bedenkt, dass du mit 24 Bildern pro Sekunde erst ein flüssiges Bild hast, wird das also knapp.

Die Kippung kannst du nur mit einem Relationsystem herausfiltern, da dein Kopf sich ja nicht nur in einer Ebene dreht.

Hab ich dir jetzt geholfen oder deine Träume zerstört? :smiley:

Kleine Korrektur: Nach Messung sind es durchschnittlich 30 MILLISekunden bis zum nächsten Meßwert Besch.sensor.

Ich habe noch einen Orientierungssensor gefunden. Der behebt das Problem, das ich habe eigentlich ganz gut, nur hat der eine geringe Auflösung: Der eine Sensor bewegt sich von 0 bis 360° Horizontal, der andere mißt die Neigung in 1°-Schritten. Bei kleinen Bewegungen ruckelt das stark, weil ich mich eben nicht um 1 ganzes Grad drehe. Auch gibt es eine Verschiebung, sprich schaue ich auf die einen Seite, dann woanders hin, dann zurück komme ich nicht an gleicher Stelle raus.

Dennoch ist das bisher am besten. Hast du eine Idee, wie ich diese beiden Sensoren kombinieren kann?

Ja. Ziel ist eine relative Mausbewegung, also ganz im Sinne des Meßwertes, der ja den Unterschied vom einen Meßwert zum nächsten beschreibt soll die Maus entsprechend ein Stück bewegt werden. Allerdings soll natürlich das Schauen etwa nach ganz links auch wieder zum Schauen nach ganz links im Spiel führen, das heißt letztlich eine Art absolutes Koordinatensystem eingehalten werden, sodaß die Werte reproduziert werden können und sich das System nicht ständig neu „eicht“.

einer Drehmatrix."
Wie sieht die hier aus?

Wikipedia listet alle Drehmatrizen in R3. Da das Handy scheinbar nur um eine Hauptachse verkippt ist, nimmst Du einfach die passende (wahrscheinlich y). Anschließend multiplizierst Du alle Beschleunigungsvektoren mit Ry(-α), wenn das Handy um α verkippt ist.