Jump to content

Mein IMU-Brick rotiert


Plenz

Recommended Posts

Ich weiß nicht, was ich gemacht habe - Kabel abgezogen und wieder angeschlossen, mal den Brick Viewer und mal mein Programm benutzt - aber zur Zeit "rotiert" mein IMU-Brick. Das heißt, ich bewege ihn nicht, aber die Werte roll, pitch und yaw beschreiben Vollkreise, jeder mit seiner eigenen Geschwindigkeit. Roll ist am schnellsten, yaw am langsamsten. (Ich benutze den Orientation Callback wegen der nahe angebrachten Motoren, die das Magnetfeld stören.)

 

Gibt es eine Erklärung dafür? Was soll ich tun?

 

Link to comment
Share on other sites

  • Replies 51
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Posted Images

Es hat heute morgen bereits funktioniert, d.h. (es geht ja um meinen Kamera-Stabilisator) "roll" ausgeglichen, "pitch" hatte ich noch nicht programmiert.

 

Ich glaube, ich habe die Ursache gefunden: ich hatte irgendwann mal Convergence Speed auf 0 gesetzt. In der Beschreibung steht etwas über Fehler, die dann nicht mehr ausgeglichen werden.

 

Was mir noch auffällt: dass im Brickviewer ständig die X-Beschleunigung um die 60 mG pendelt. (Man könnte ja mal ausrechnen, wie lange es dauert, bis Lichtgeschwindigkeit erreicht ist...)

 

Und noch was: die Werte von Roll, Pitch und Yaw hängen offensichtlich sehr eng miteinander zusammen. Wenn ich den IMU-Brick um 90° pitche and dann um 90° yawe, dann verändert sich auch der Roll-Winkel, obwohl ich eigentlich gar keine Rollbewegung ausgeführt habe. Gibt es irgend eine Möglichkeit, die Yaw-Bewegung zu ignorieren oder herauszurechnen? Sollte ich vielleicht besser mit den Werten von Angular Velocity rechnen?

 

 

 

Link to comment
Share on other sites

Ja, wenn du die Convergence Speed auf 0 setzt wird der Magnetometer nicht mehr verwendet! Da ist der Fehler den du hattest zu erwarten.

 

Roll Pitch und Yaw sind Eulerwinkel, d.h. die haben eine feste Reihenfolge in der sie angewendet werden: http://de.wikipedia.org/wiki/Eulersche_Winkel Du kannst nicht einfach einen der Werte losgelöst von den anderen beiden betrachten. Man kann das allerdings in der Tat rausrechnen.

 

Ich hab die Rechnung für yaw hier damals schon einmal getan: http://www.tinkerunity.org/forum/index.php/topic,162.msg549.html#msg549

 

Du multiplizierst einfach den Quaternion mit einem Vektor der auf die Y-Achse zeigt. Nach der Multiplikation kannst du den Winkel zwischen der X und Y-Komponente des resultierenden Quaternion ausrechenen (atan2) und schon hast du einen super Kompass gebaut. Da werden dann auch Drehungen um andere Achsen rausgerechnet, was nicht der Fall ist wenn du nur einen Magnetometer hast! Wenn man bedenkt wieviel Mathematik man normalerweise brauch um sowas aus Beschleunigungssensor/Magnetormeter Werten zu berechnen ist das richtig Cool 8).

 

Pseudocode:

q = getQuaternion()
v1 = Vector3d(0, 1, 0)
v2 = q*v1
angle = atan2(v2.x, v2.y)

Link to comment
Share on other sites

Ich kapier das alles nicht. Ich habe Motoren mit störendem Magnetfeld, also ist es doch naheliegend, Convergence Speed auf Null zu setzen, weil ich den Magnetometer sowieso nicht nutzen kann.

 

Und das mit den Winkeln ist so: wenn du schweres Gepäck in deinen Kofferraum tust, dann geht dein Auto vorn hoch, und dein Abblendlicht blendet alle Leute. Deshalb musst du es um einen Winkel x nach unten korrigieren. Dieser Winkel x ist immer der selbe, auch wenn du nach links oder nach rechts abbiegst. Dieser Winkel interessiert mich - unabhängig von der Fahrtrichtung. Und dann auch noch der Winkel quer dazu, also z.B. wenn der Fahrer 50 kg wiegt und der Beifahrer 150 kg, dann geht der Wagen rechts in die Federn, ebenfalls unabhängig von der Fahrtrichtung. Was ich wirklich am allerwenigsten brauche, ist ein Kompass.

 

Das jetzt mal auf die Schnelle, ich werde heute abend weiter experimentieren. Jedenfalls vielen Dank für die Formel.

 

Link to comment
Share on other sites

Ich werde die Dokumentation am Montag erweitern um ein Paar Formeln zum Umrechnen für die wichtigsten Sachen. Was du vor hast ist auf jedenfall möglich, geht aber nicht gut über die Eulerwinkel (getOrientation).

 

Solche Fragen werden jetzt wohl öfter kommen, wir haben ja einige IMUs verschickt. Ich vermute im Moment setzen wir ein bisschen zuviel Mathematik voraus!

 

Bzgl. der Convergence Speed: Wenn du die auf 0 setzt und die Gyroskope auch nur einen absolut minimalen Fehler im Stillstand haben (was sie immer haben, das geht gar nicht anders) addiert sich dieser Fehler auf und die IMU dreht sich um die fehlerhafte Achse des Gyroskops.

Link to comment
Share on other sites

Solche Fragen werden jetzt wohl öfter kommen, wir haben ja einige IMUs verschickt. Ich vermute im Moment setzen wir ein bisschen zuviel Mathematik voraus!

Es hapert so ziemlich an allem  :-\

Mathematik - bei Ebener Trigonometie kann ich noch gut mithalten, aber wenn ich die riesigen Klammern mit wirrem Zeugs in dem Wikipedia-Artikel über Eulersche Zahlen sehe... nee danke!

Problematik - Worum geht es überhaupt? Wenn ich Koordinaten von einem System in ein anderes umrechnen will, brauche ich das alles doch gar nicht, oder?

Theorie und Praxis - Der ganze Aufwand - dachte ich bisher - dient zur Vermeidung des Gimbal Locks. Das kommt, wenn bei einer dreidimensionalen Kardanaufhängung zwei Achsen die gleiche Richtung einnehmen. Interessiert mich nicht, weil ich nur eine zweidimensionale Kardanaufhängung habe, die sich maximal um 60° nach beiden Seiten verdrehen kann. Scheint aber dennoch irgendwie wichtig zu sein.

Technik - für Hubschraubermodelle kann man einfache Gyroskope kaufen, die ermitteln den Yaw-Winkel und steuern den Heckrotor - ohne Magnetometer und höhere Mathematik. Nun dachte ich, wenn ich getOrientation() benutze, tue ich so, als ob in dem IMU-Brick drei solcher Gyroskope eingebaut wären, und den Rest ignoriere ich einfach.

Grundlagen - Der IMU-Brick braucht also ein Magnetfeld wegen der Fehlerkompensation. Bei mir sind aber diese störenden Motoren. Braucht er gar nicht das Erdmagnetfeld, sondern einfach nur irgend ein beliebiges Magnetfeld?

 

Ich werde die Dokumentation am Montag erweitern um ein Paar Formeln zum Umrechnen für die wichtigsten Sachen.

Dafür wäre ich dir unendlich dankbar. Aber bitte keinen Pseudocode ("addiere einen Vektor"), sondern fertige Formeln, bei denen man nur noch den Syntax der jeweiligen Programmiersprache anpassen muss.

 

Link to comment
Share on other sites

Ich sehe gerade, in der Doku hat sich ja allerhand getan. Nicht nur die zusätzlichen Formeln, sondern auch eine ausdrückliche Empfehlung, den Magnetometer in der Nähe von Motoren neu zu kalibirieren. Das beantwortet zwar nicht meine Verständnisfragen, aber egal - Hauptsache, ich weiß, wie ich weiter vorgehen muss. Ich bin gespannt, was dabei herauskommt...

Link to comment
Share on other sites

Wenn du es richtig kalibrieren willst musst du schon die ganze Apparatur mit Motor drehen ;D.

 

Ich hab mal auf die Schnelle folgendes ausgerechnet:

q = getQuaternion()
v1 = Vector3d(0, 0, 1)
v2 = q*v1
x_angle = atan2(v2.y, v2.z)
x_angle = atan2(2*y*z - 2*x*w, w*w + z*z - x*x - y*y)*180/PI

q = getQuaternion()
v1 = Vector3d(0, 0, 1)
v2 = q*v1
y_angle = atan2(v2.x, v2.z)
y_angle = atan2(2*w*y + 2*x*z, w*w + z*z  -x*x - y*y)*180/PI

q = getQuaternion()
v1 = Vector3d(0, 1, 0)
v2 = q*v1
z_angle = atan2(v2.x, v2.y)
z_angle = atan2(-w*y + x*y + y*x - w*w, w*w + y*y - z*y - x*x)*180/PI

 

Dich interessieren diese beiden Zeilen:

x_angle = atan2(2*y*z - 2*x*w, w*w + z*z - x*x - y*y)*180/PI
y_angle = atan2(2*w*y + 2*x*z, w*w + z*z  -x*x - y*y)*180/PI

 

Evtl. noch ein +180 oder ein +360 % 360 hinten dran, je nachdem wo du den 0-Punkt haben willst. Dabei sind x,y,z und w die Quaternionen die du per Getter oder Callback bekommst.

 

Ich hab vor dazu noch genau zu schreiben wie man das herleitet und warum das so ist, damit das einfacher zu verstehen ist.

 

Muss aber morgen früh zum Zahnarzt, wird Zeit das ich ins Bett komme  :-\.

 

PS: Hab das gerade auf einem Blatt Papier umgestellt und nicht getestet, also alles ohne Gewähr :).

Link to comment
Share on other sites

Vielen Dank erst mal, ich hab's gerade mal auf die Schnelle ausprobiert. Die schlechte Nachricht: x_angle und y_angle verdrehen sich immer gleichzeitig. Die gute Nachricht: sie sind tatsächlich unabhängig von der Fahrtrichtung. Vielleicht sollte ich das erst mal ohne Motoren in der Nähe testen, aber ich muss ins Büro  :(

 

Ich hoffe, der Zahnarzt hat dich nicht schachmatt gesetzt, und was das Bett betrifft: Schlaf ist völlig überbewertet, in Wirklichkeit ist das nur so ein primitiver Kafee-Ersatz.  ;D

Link to comment
Share on other sites

zu 2) Ich zitiere einfach mal vom Blog:

Bei der automatischen Kalibrierung hatten wir Probleme das Magnetfeld der Servomotoren vernünftig rauszurechnen (dies ist definitiv möglich und wir werden das auch auf Dauer tun). Damit sich das ganze nicht noch mehr verzögert haben wir bei den ersten 250 IMUs die Magnetometer erstmal schnell von Hand kalibriert.

Link to comment
Share on other sites

Ich war heute mittag mal kurz zu Hause und habe ein bisschen getestet (hab momentan echt nichts anderes im Kopf als IMU).

 

Und zwar: IMU raus aus allem, Motoren weit weg, Magnetometer kalibiriert und mein Programm so verändert, dass es mir kontinulierlich die "nackten" Werte von x, y, z und w ausgibt. Und dann das Ding waagerecht auf dem Tisch gedreht.

 

Schon mal einfach: z und w sind immer etwa Null.

 

Aber nun der Schock: wenn ich das Ding um 180° nach links drehe, bekomme ich andere Werte für x und y, als wenn ich es um 180° nach rechts drehe! Zweimal haargenau die gleiche Lage, aber verschiedene Werte:

-180° x=-0,37 y=+0,93

+/-0° x=-0,97 y=-0,25

+180° x=+0,46 y=-0,88

 

Weitere Experimente mit genicktem IMU-Brick habe ich mir gleich geschenkt. Das Ding ist einfach zu hoch für meinen armen Verstand.  :'(

 

 

 

Link to comment
Share on other sites

Rotation um nur eine Achse bewirkt häufig auch eine Rotation um eine andere Achse...

 

Du meinst bei den Euler Winkeln? Dort ist das zu erwarten! Es geht dabei immer um die Lage im Raum, nicht um eine einzelne Achse. D.h. wenn du die 3 Winkel vom Startpunkt in der richtigen Reihenfolge drehst kommt am Ende die Lage des Bricks dabei raus.

 

Dabei bleibt es nicht aus dass sich alle Winkel ändern wenn du nur um einen drehst.

 

Ich hab hier nochmal was dazu geschrieben: http://www.tinkerforge.com/doc/Hardware/Bricks/IMU_Brick.html#quaternions-vs-euler-angles

 

Aber nun der Schock: wenn ich das Ding um 180° nach links drehe, bekomme ich andere Werte für x und y, als wenn ich es um 180° nach rechts drehe! Zweimal haargenau die gleiche Lage, aber verschiedene Werte:

-180° x=-0,37 y=+0,93

+/-0° x=-0,97 y=-0,25

+180° x=+0,46 y=-0,88

 

Weitere Experimente mit genicktem IMU-Brick habe ich mir gleich geschenkt.

 

Hehe, das ist bei Quaternionen so, es gibt mehr als eine Darstellung für die gleiche Lage :).

Link to comment
Share on other sites

Wie gesagt, hatte ich beobachtet, dass sich die Winkel x und y gleichzeitig verändern, auch wenn ich den IMU-Brick nur um eine Achse drehe. Entweder stimmt was mit meiner Kalibration nicht oder mit deinen Formeln oder mit meinem Verständnis.

 

Damit wir von der selben Sache reden, habe ich eine Skizze gemacht. Ein Flugzeug hat Pitch=0°, wenn es normal fliegt, und Pitch=-5°, wenn es landet. Und Roll=0°, wenn es geradeaus fliegt, und Roll=10°, wenn es sich in die Kurve legt. Und das alles völlig unabhängig voneinander.

 

Sollte ich eigentlich mit deinen Formeln genau diese Ergebnisse bekommen? Oder sind dafür doch noch andere Formeln notwendig?

ropi.png.766b089fb34bdc547b7b019efc46156c.png

Link to comment
Share on other sites

Also, ich glaube ich verstehe ich etwas grundlegendes nicht....

 

Wenn ich den IMU Brick bei hochfahren sich seine Position finden lasse, für 5 Sekunden (über convergence speed gesteuert) und nur mit Quaternion auslese, welche ich dann später umrechne, erwarte ich irgendwie ein anderes verhalten.

 

Ich habe mein Vorgehen mir aus verschiedenen Beiträgen "zusammen gesammelt"....

 

Ich speichere eine "Orientation und lese dann Quaternions aus...

Danach konjugieren und ich durch entsprechende Formeln in die einzelnen Winkel

(x/y/z, bzw. roll/pitch/yaw) umrechnen.

 

Wenn ich aus einer "Nullposition" um genau eine Achse "kippe / drehe" dann würde ich erwarten, dass auch nur ein Winkel sich ändert. Und da isst nicht immer der Fall. Und der Z_Angle verhält sich völlig sonderbar, zeigt aber keinesfalls die Rotation um die entsprechende Achse in Grad an ...

 

Ändere ich den Pitch, dann bitte nur Pitch-Winkel ändern, Selbiges für Roll oder Yaw. Solange ich aber diese Werte nicht auf die Reihe bekomme brauche ich gar nicht an einen "Tilt Compensated" Compass zu denken :(

 

Dies hier sind die Formeln, die ich verwende (Ruby)

 

wn = w * rel_w - x * rel_x - y * rel_y - z * rel_z
xn = w * rel_x + x * rel_w + y * rel_z - z * rel_y
yn = w * rel_y - x * rel_z + y * rel_w + z * rel_x
zn = w * rel_z + x * rel_y - y * rel_x + z * rel_w
  
  x_angle = Math.atan2(2*yn*zn - 2*xn*wn, wn*wn + zn*zn - xn*xn - yn*yn)*180/Math::PI
  y_angle = Math.atan2(2*wn*yn + 2*xn*zn, wn*wn + zn*zn  -xn*xn - yn*yn)*180/Math::PI
  z_angle = Math.atan2(-wn*yn + xn*yn + yn*xn - wn*wn, wn*wn + yn*yn - zn*yn - xn*xn)*180/Math::PI

 

Was ist nun mein Denkfehler....?

 

Vielen Dank im Voraus, Dirk

 

Link to comment
Share on other sites

@ROSEDOLA: Ah, das hatte ich nicht genau gelesen. Die Formeln beziehen sich schon auf das Original System. Wenn du alles komplett mit Quaternionen rechnen möchtest (wie ich das z.B. im brickv mache), kannst du so vorgehen. Du könntest jetzt aus dem resultierenden Quaternion einen Vektor (x, y, z) und einen Drehung um diesen Vektor ausrechnen und z.B. diese Drehung ausführen um zurück zu deinem Nullpunkt zu kommen.

 

@Alle: Um das nochmal klarzustellen, die einzelnen Winkel sind nunmal voneinander abhängig, ich werde den Text in der Dokumentation nochmal überarbeiten diesbezüglich, da suggeriere ich im Moment anderes befürchte ich.

 

Nur damit euch klar ist wovon ich rede: Nehmt doch mal die IMU und dreht um die X Achse 45°, dann um die Y Achse 45° und dann zurück um die X Achse 45° und dann zurück um die Y Achse 45°. Nach diesen drehungen hat sich die Z Achse um ein paar Grad verschoben, obwohl ich nie um die Z Achse gedreht hab! Dagegen kann man nichts machen :).

 

Sagt mir doch mal bzgl. welchen Koordinatensystems ihr welche Winkel haben wollt, dann versuche ich dafür Formeln aufzustellen.

 

 

Nochmal anders: Wenn ihr euch im Brick Viewer die Orientation (roll, pitch, yaw) anguckt und aufschreibt und dann in der richtigen Reihenfolge zurückdreht (erst roll, dann yaw, dann pitch), dann kommt ihr wieder zurück zum 0 punkt (also roll, pitch, yaw = 0, 0, 0). Egal welche noch so interessanten Winkel während der Drehung angezeigt werden :).

Link to comment
Share on other sites

Vielleicht würde es helfen wenn man anstatt mit den Winkeln mit einem Bezugspunkt handeln würde.

 

Also z.B. die USB Buchse auf der Platine,

nachdem Kalibrieren ist sie bei (0,1,0) der Nullpunkt ist die Mitte des Bricks.

wenn man jetzt die Umrechnung der Quaternionen angibt die einem sagt wo der Punkt tatsächlich ist würde glaube ich schon einigen Helfen.

 

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...