Winkel aus Beschleunigungsdaten berechnen
-
Ich habe einen 3-Achsigen Beschleunigungssensor und möchte die Neigungswinkel in x und y Richtung ausrechnen um die Neigung des Geräts auf dem der Sensor sitzt darstellen zu können.
Ich muss also einfach eine Fläche zwischen x und z Achse sowie zwischen y und z Achse aufspannen und dazu jeweils den Orthogonalen Vektor bestimmen, also:
sowie
.
Wobei nx und ny die Neigung von x und y ist.In der opengl Darstellung kann ich dann also machen:
glRotatef(nx*180.0/math.pi, -1.0, 0.0, 0.0) # Rotate board on X glRotatef(ny*180.0/math.pi, 0.0, 0.0, 1.0) # Rotate board on Y
Wenn ich eins der rotates auskommentiere funktioniert es. Ich kann die Platine um die nicht auskommentierte Achse drehen und die grafische Darstellung passt perfekt (in der Achse). Wenn ich beide Zeilen benutze funktioniert es fast überall perfekt, sobald ich allerdings bei der X Achse die 0° oder 180° (d.h. ich stell die Platine auf die Kante) erreiche, dreht sich die Y Achse um 180°, allerdings nicht abrupt sondern schön smooth im Bereich von 10 bis -10°.
D.h., angenommen ich hab die Y-Achse auf 0°, komme bei der X-Achse bei 10° an und drehe in negative Richtung, dann steigt die Y-Achse beim drehen vom 10 auf -10° auf 180° an.
Das Gleich Problem tritt symmetrisch mit der Y-Achse auf wenn ich sie auf die Kante stelle.Wenn man ganz abstrakt drüber nachdenkt ist dieses Verhalten auch verständlich, wenn ich die Platine auf die Kannte in Richtung X-Achse stelle und hin und her Wippe, ändert sich der Wert von Z und X (Z stark und X nicht so stark in die gleiche Richtung, dadurch berechnet sich die neue X-Neigung [die korrekt ist]), gleichzeitig bleibt allerdings Y gleich und Z entfernt sich, also steigt der Wert der bei atan2(y, z) raus kommt logischerweise. Allerdings ist diese Berechnung rein geometrisch auf einem Blatt Papier betrachtet doch korrekt...
Das bringt mich gerade zur Verzweiflung, kann mir irgendeiner erklären wie man das korrekt berechnet oder wo mein Denkfehler ist?
-
Ich hab das Problem von oben gefunden, der einer Achse ist durch die 3-Dimensionalität immer abhängig von beiden anderen Achsen, deswegen muss man zuerst die Norm davon berechnen:
bzw.
.Das geht jetzt leider nur noch für z > 0... hat jemand eine Idee wie ich das auf alle z erweitern kann? das Vorzeichen von z vor die Norm schreiben geht nicht.
-
@borg
Aus deinem Codebeispiel entnehme ich dass du eine Koordinatentransformation auf deinen Sensorwert (x, y, z) machen möchtest um damit die Beschleunigungswerte (Winkel) bezogen auf ein (globales) Koordinatensystem zu bestimmen. Denn wenn man mal annimmt dass der Sensor auf einem Auto montiert ist, liefert der Sensor die Beschleunigung immer Bezug auf das Sensorboard. Und da man damit nicht viel anfangen kann, definiert man sich ein Weltkoordinatensystem und transformiert die Sensordaten in das Weltkooridnatensystem, damit die Sensordaten unabhängig von der Lage des Sensorboards ist. Liege ich damit richtig ?Wenn ja, dann hast du die Begriffe Neigungswinkel und Rotationswinkel verwechselt sowie die Begriffe Weltkoordinatensystem und lokales Koordinatensystem (Benutzerkoordinatensystem) missachtet.
-
Bitte ein Bit schrieb:
um damit die Beschleunigungswerte (Winkel) bezogen auf ein (globales) Koordinatensystem zu bestimmen.
nein, ich hab Beschleunigungswerte (G, ich hab eben keine Winkel) und möchte anhand dieser Die Lage des Sensors im Raum (Weltkoordinatensystem) berechnen. D.h. ich möchte Winkel berechnen um die ich die X sowie Y-Achse drehen muss um die Lage des Sensors darstellen zu können.
Bitte ein Bit schrieb:
Denn wenn man mal annimmt dass der Sensor auf einem Auto montiert ist, liefert der Sensor die Beschleunigung immer Bezug auf das Sensorboard.
Das ist hier nicht der Fall. Der Sensor kann sich in einer beliebigen Lage im Raum befinden (auch auf dem Kopf, nur da hab ich Probleme) und es kann davon ausgegangen werden, dass die einzige Beschleunigung die zur Zeit der Messung auftritt die Erdbeschleunigung ist (sprich der Sensor bewegt sich nicht).
edit: Das ganze scheint so nicht lösbar zu sein. Ich habe eine z Wert, einen Rollwinkel und einen Nickwinkel. für z >= 0 sind die Werte korrekt. für z < 0 hab ich ein Problem, denn es gibt 3 Möglichkeiten dafür das z < 0 eintritt:
abs(roll) > 90° oder abs(pitch) > 90° oder (abs(roll) > 90° und abs(pitch) > 90°)
Es ist schlicht nicht Möglich das mit Fallunterscheidungen zu lösen, da diese 3 Fälle nicht mehr unterscheidbar sind. Die ganze Sache verliert bei negativen z Werten ihre Symmetrie. Heißt dass, das es ist mit einem 3-Achs Beschleunigungssensor ohne Zusatz von Gyroskopen oder Magnetometern nicht möglich die genaue Position dessen im Raum zu berechnen wenn er auf dem Kopf steht?
-
Ok dann hast du nur ein einfaches kinematisches Problem.
Man benutzt hier einen allgemeinen Ansatz um das Problem zu lösen. Nehmen wir mal an dass dein Sensor h = (0 0 -1)^T als Wert bei exakt horizontaler Ausrichtung anzeigt. Und nehmen wir mal O.B.d.A. an dass das Sensorboard erst eine Rotation um die X-Achse und danach eine Rotation um die verschobene Y-Achse macht. Dann gilt: RotY(beta) * RotX(alpha) * h = (x, y, z)^T wobei RotY und RotX die entsprechenden Rotationsmatrizen sind und (x y z) dein Sensorwert bei unbekannter Lage ist. Wenn du diese Gleichung nun ausführlich hinschreibst und dann nach beta und alpha umstellst, kommst du auf die richtigen Gleichungen.
Bei einem verwandten Problem (anderes h) kam als Lösung alpha = atan2(x/y), beta = asin(-z) heraus (Nur mal so als Hinweis).
Quellen:
http://de.wikipedia.org/wiki/Koordinatentransformation
http://de.wikipedia.org/wiki/Drehmatrix
http://de.wikipedia.org/wiki/Denavit-Hartenberg-Transformation
-
Mh, klingt logisch, dann wären also zu lösen:
$ \begin{pmatrix}\cos{b} & 0 & \sin{b} \\ 0 & 1 & 0 \\ -\sin{b} & 0 & \cos{b}\end{pmatrix} \cdot \begin{pmatrix}1 & 0 & 0 \\ 0 & \cos{a} & -\sin{a} \\ 0 & \sin{a} & \cos{a}\end{pmatrix} \cdot \begin{pmatrix}0 \\ 0 \\ 1\end{pmatrix} = \begin{pmatrix}x \\ y \\ z\end{pmatrix} $Das ergibt:
\begin{align*} \cos{b}\cdot\sin{a} &= x \\ -\sin{b} &= y \\ \cos{a}\cdot\cos{b} &= z \end{align*}Wobei a und b gesucht sind. Dabei sind a und b in [-pi,pi] sowie x, y und z in [-1,1]. Irgendwer eine Idee? Mathematica kann es nicht lösen...
-
Hallo,
also mein Tipp wäre die Drehungen mit Quarternionen zu berechnen.
Ist leichter als mit Rotationsmatrizen und Gimballock kann auch
nicht auftreten.Gruß,
Andreas
-
@borg:
Naja du bist doch schon fast fertig. Denn nach der zweiten Formel gilt: -sin(b) = y -> b = asin(-y). Teilt man die erste Formel durch die dritte bekommt man sin(a)/cos(a) = x/z -> tan(a) = x/z -> a = atan2(x/z).Beachte aber dass die Rotationswinkel nicht vertauscht werden können, deine Rotationsreihenfolge ist fix!