AuronX Posted June 5, 2012 at 08:14 PM Share Posted June 5, 2012 at 08:14 PM Die Frage ist ob es möglich ist das ganze in einem nciht gimbal-lock-freien, aber dafür einfachen Koordinatensystem anzugeben. Weil im Endeffekt geben die Quaternionen ja die neue Position des USB (oder welcher Seite auch immer) an, aber eben nur nicht eindeutig. Das heißt es gibt mehrere Varianten die gleiche Lage zu beschreiben, allerdings versteht das keiner (mich eingeschlossen) ^^ Ich weiß daher auch nicht, ob es ohne weiteres möglich ist die mehrdeutigen Quaternionen in eindeutige "gimbal-lock" Koords umzurechnen. Wäre okay, wenn es ginge, weil viele das Gimbal-Lock nicht stört. Quote Link to comment Share on other sites More sharing options...
borg Posted June 5, 2012 at 08:18 PM Share Posted June 5, 2012 at 08:18 PM @ThomasKI: Damit stellst du aber nur 2 Achsen dar oder? Also wenn ich den IMU Brick jetzt vor mir halte und um die Y Achse drehe verändert sich die Position des USB Steckers ja nicht! Wenn ich jetzt her gehe und zusätzlich zum Vektor (x,y,z) des USB Steckers auch noch eine Drehung angebe um diesen Vektor, dann habe ich Quaternionen!!!! Edit: Vielleicht sollte ich das mit USB Stecker als Bezungspunkt trotzdem mal durchrechnen und dann so bezeichnen, also Position des USB Steckers in eine Würfel mit Ausmaß 1 und Drehung um diesen Vektor. Dann hab ich immernoch eine Darstellung die ich 1:1 wieder zu dem Quaternion umrechnen kann und zurück, aber vielleicht ists einfacher zu benutzen? Das gucke ich mir morgen mal an, kann eigentlich gar nicht schwer sein, ich tue das im Brick Viewer ja quasi schon. Quote Link to comment Share on other sites More sharing options...
ThomasKl Posted June 5, 2012 at 08:30 PM Share Posted June 5, 2012 at 08:30 PM @borg ja ich weiß ich meinte nur als Beispiel, dass man leicht mit der Hand und dem Kopf nachvollziehn kann. Und wenn man es mal in 2D verstanden hat (also z.B. ohne Rotation um die Y-Achse) ist der Weg zu den Quaternionen wie du richtig sagst nicht mehr weit. Quote Link to comment Share on other sites More sharing options...
Plenz Posted June 5, 2012 at 09:01 PM Author Share Posted June 5, 2012 at 09:01 PM kann eigentlich gar nicht schwer sein, ich tue das im Brick Viewer ja quasi schon. Genau! Diese Quaterdinger interessieren mich nämlich überhaupt nicht, mich interessiert nur die Verdrehung gegenüber der Horizontalen. Und die sieht man im Brick Viewer ganz hervorragend. Anbei ein paar Screenshots: 1.) Der IMU-Brick liegt flach auf dem Tisch 2.) Der IMU-Brick um 45° nach rechts gekippt (links hoch, rechts runter) 3.) Den gekippten IMU-Brick um 90° auf den Tisch nach rechts gedreht 4.) Den gekippten IMU-Brick um weitere 90° auf den Tisch nach rechts gedreht Die grafische Darstellung ist im Grunde genommen immer die selbe: ich sehe den IMU-Brick um 45° nach rechts (um die Achse des USB-Steckers) gekippt. Unabhängig von allen anderen Winkeln! Unabhängig von der Drehrichtung! Alles, was ich brauche, ist eine Formel, die mir diese "45°" ausspuckt, und zwar für alle Screenshots 2.) bis 4.) und natürlich noch eine zweite Formel für das Kippen nach vorn/hinten. Die jetzt in der Doku eingebauten drei Formeln liefern das jedenfalls nicht, ich habe es gerade getestet. Quote Link to comment Share on other sites More sharing options...
ThomasKl Posted June 5, 2012 at 11:48 PM Share Posted June 5, 2012 at 11:48 PM Wenn ich es richtig verstanden habe besteht ein Quaternion im Prinzip aus zwei Elementen einem Richtungsvektor (x,y,z) und einem Winkel (w). Den Richtungsvektor kann man sich nun als einen Pfeil auf der Platine vorstellen z.B. vom Mittelpunkt der Platine zur USB Buchse. x,y,z sind jetzt Koordinaten in einem äußeren Koordinatensystem, dessen Ursprung mit dem Mittelpunkt der Platine zusammenfällt. Um nun zu einer mittels xyzw vorgegebenen Position zu kommen kann ich zwei Wege gehe entweder ich drehe erst die Platine um den winkel w, die Drehachse ist dabei der aufgezeichnete Pfeil und bewege dann die USB Buchse zur mit xyz angegebenen Position ohne dass sich der Mittelpunkt verschiebt, oder ich bewege erst die USB Buchse und drehe dann um den angegebenen Winkel. Die Koordinaten beziehen sich aber immer auf ein festes Äußeres koordinatensystem also z.b. x=nord y=süd Wenn ich richtig verstanden habe was Plenz möchte, dann ist ihm das äußere Koordinatensystem relativ egal und er ist nur an den beiden Winkeln zur Z-Achse interessiert, Das ist einmal der Winkel USBBuchse-Mittelpunkt-äußereZAchse und einmal StackVerbinder-Mittelpunkt-außereZAchse der erste Winkel ist einfach da es der Winkel zwischen den Vektoren (x,y,z) und (0,0,1) um den zweite Winkel zu berechnen muss man erst den Vektor (a,b,c) ableiten der senkrecht auf dem Richtungsvektor steht und den winkel w erfüllt, dass ist vermutlich etwas mehr Aufwand, da fällt mir spontan auch keine einfache Ableitung ein. Insgesamt wäre es mal interessant zu wissen wie xyzw aussehen wenn man neu kalibriert hat, ist es möglich die Orientierung des Richtungsvektor zur Platine selbst bestimmen oder wird da immer mit dem gleichen gerechnet. EDIT: In der Docu sind ja beispiele genannt um einen vektor zu transformieren, also um plenz anforderung zu erfüllen muss einmal der Vektor (1,0,0) transformiert werden und einmal der Vektor (0,1,0) bestimmt man nun für jeden der beiden transformierten vektoren den winkel zur zAchse (0,0,1) sollte das Problem eigentlich gelöst sein. Quote Link to comment Share on other sites More sharing options...
Plenz Posted June 6, 2012 at 11:01 AM Author Share Posted June 6, 2012 at 11:01 AM der erste Winkel ist einfach da es der Winkel zwischen den Vektoren (x,y,z) und (0,0,1) Für mich ist das leider überhaupt nicht einfach mangels jeglicher Kenntnisse über Vektorrechnung. Aber wenn es für dich einfach ist, wäre ich dir für eine nachprogrammierbare Formel sehr dankbar. Quote Link to comment Share on other sites More sharing options...
ThomasKl Posted June 6, 2012 at 12:34 PM Share Posted June 6, 2012 at 12:34 PM der winkel w zwischen zwei vektoren (a,b,c) und (x,y,z) lässt sich mit w = acos((a*x+b*y+c*z)/(sqrt(a*a+b*b+c*c)*sqrt(x*x+y*y+z*z))) berechnen wenn a=b=0 und c=1 ergibt sich w = acos(z/sqrt(x*x+y*y+z*z))) was aus der Documentation nicht ganz klar wird, ist in welche Richtung die angegeben Transformation abläuft also vom äußerem Koordinatensytsem (festgelegt bei der Kalibration) zu Koordinaten relativ zur Platine oder anders herum Quote Link to comment Share on other sites More sharing options...
Plenz Posted June 6, 2012 at 02:43 PM Author Share Posted June 6, 2012 at 02:43 PM OK, mal kurz getestet. IMU-Brick um 45° geneigt (USB-Stecker runter, Richtungs-LED rauf) und dann das Ganze auf dem Tisch hin und her gedreht. w nach der obigen Formel ist bei -180° anders als bei +180°. Wie gesagt, brauche ich aber eine "45", egal wie der Brick auf dem Tisch gedreht ist. Quote Link to comment Share on other sites More sharing options...
ThomasKl Posted June 6, 2012 at 03:52 PM Share Posted June 6, 2012 at 03:52 PM Der Winkel hängt natürlich von dem bei der Kalibration gesetzten Richtungsvektor ab, wo der tatsächlich liegt weiß ich nicht, der einfachheithalber habe ich die USBBuchse angenommen. aber das nach oben berechnete w sollte konstant sein wenn du das Brick um die ZAchse drehst, wenn ich dich richtig verstanden habe ist dem so oder? Quote Link to comment Share on other sites More sharing options...
The_Real_Black Posted June 6, 2012 at 05:28 PM Share Posted June 6, 2012 at 05:28 PM Es wäre schön wenn Z nach oben gerichtet wäre, dann würde es nicht immer von +-180 schwanken... eine Schwankung um +-0 ist einfacher zu verarbeiten. Im Moment ist bei mir RPY 0,0,0 der Brick auf dem Kopf liegend mit X-Achse(+) nach Norden. Schöner wäre es 180 grad gedreht also -X Achse nach Süden. Eine Drehung um Z Achse sollte dann eindeutig von 0 bis +-180 laufen oder besser noch von 0 bis zu 360. Wie wäre es mit einer Kompasumrechnung Drehung von Norden weg in nur einer Ebene? Ansonsten sollte es eine eindeutige Drehungsangabe für die XY Ebene geben. Edit: Die Drehung um Brickmitte finde ich gut. Quote Link to comment Share on other sites More sharing options...
Plenz Posted June 6, 2012 at 10:56 PM Author Share Posted June 6, 2012 at 10:56 PM aber das nach oben berechnete w sollte konstant sein wenn du das Brick um die ZAchse drehst, wenn ich dich richtig verstanden habe ist dem so oder? Nein, leider nicht. Ich habe heute noch mal zwei Versuche gemacht: 1.) IMU-Brick waagerecht gelegt und langsam um 360° gedreht 2.) IMU-Brick ca. 45° gekippt und langsam um 360° gedreht Mit "gekippt" meine ich: USB-Stecker runter, LEDs rauf. Beim Drehen (per Hand) habe ich x,y,z,w mitgeloggt. Diese Werte habe ich in einer Excel-Tabelle gespeichert und mit den bekannten Formeln ergänzt (die drei aus der Doku und die eine von ThomasKl). Ich hänge die Tabelle hier mal dran. Was ich immer noch suche: eine Formel, die mir bei der ersten Drehung konstant "0" ausgibt und bei der zweiten Drehung konstant "45". IMU_Test.xls Quote Link to comment Share on other sites More sharing options...
borg Posted June 6, 2012 at 11:49 PM Share Posted June 6, 2012 at 11:49 PM So, nächster Versuch . In dem neuen Beispiel sollte alles untergebracht sein was hier gefragt war: http://www.tinkerforge.com/doc/Hardware/Bricks/IMU_Brick.html#how-to-get-angles-that-are-independent Erst wird eine Bezugsposition festgelegt, diese Position legt fest wo 0 Grad für alle Winkel sind. Danach sollten die Winkel für x, y und z berechnet werden. Gimbal Locks sind bei +90 und -90° bei allen Achsen, in etwa einem 15° Radius um den Gimbal Lock fangen die Werte an ungenau zu werden und beim Überspringen können Achsen um 180° springen (das ist korrektes verhalten). Wenn das nicht ausreicht oder das zu ungenau ist für eure Anwendung müssen entweder Rotationsmatrizen oder direkt die Quaternionen benutzt werden, da geht kein weg dran vorbei. Hab heute den halben Tag rumprobiert, eine bessere Darstellung kriege ich mit Eulerwinkel nicht hin ! Quote Link to comment Share on other sites More sharing options...
The_Real_Black Posted June 7, 2012 at 07:30 AM Share Posted June 7, 2012 at 07:30 AM (Wir könnten einen Selbsthilfe Mathe Thread aufmachen...) Überlegung: Ich habe einen Vektor Norden diesen rotiere ich um die Achsen bzw ich Multipliziere mit der Rotationsmatrix. Danach setze ich das Ergebnis in Z = 0 und erhalte den Vektor in der XY Ebene. Nach dem Normieren bestimme ich den Winkel vom Nordvektor zum Positionsvektor und habe die globale Drehung des IMU in der Ebene oder? Ich muss mal meine Mathe Vorlesungsunterlagen zusammen suchen ^^ Habe ich irgendwas übersehen an meiner Überlegung? Quote Link to comment Share on other sites More sharing options...
Plenz Posted June 7, 2012 at 08:02 AM Author Share Posted June 7, 2012 at 08:02 AM So, nächster Versuch . Sorry, irgendwas klappt mit dem Programm nicht. Nach "Press key to exit" tut sich überhaupt nichts, erst nach dem Tastendruck kommt einmal "x: 0, y: 0, z:0". Der Code ist ja an sich verständlich, ich kann den Fehler nicht finden. Quote Link to comment Share on other sites More sharing options...
ThomasKl Posted June 7, 2012 at 08:12 AM Share Posted June 7, 2012 at 08:12 AM was mir bei den Erklärungen fehlt ist irgendwie die Information von welchem Bezugssystem ausgegangen wird. In meiner Vorstellung gibt es zwei Koordinatensysteme das des Bricks mit den x,y,z Achsen so wie sie auf dem brick aufgedruckt sind und das Äußere also die Welt mit Nord-Süd (NS), Ost-West (OW) und dem gefühlten Unten-Oben (UO). Jetzt braucht man die Transformation für Weltkoordinaten (NS,OW,UO) in Brickkoordinaten (x,y,z) und für die Transformation von Brick zu Welt koordinaten. Um das Problem von Plenz zu lösen müsste man einmal den Punkt (1,0,0) von Brick zu Welt transformieren und dann den Winkel zur UO-Achse bestimmen. Und dann das gleiche nochmal mit dem Punkt (0,1,0). wenn ich das richtig verstanden habe dann Transformiert die in der Api angegebene Matrix Brickkoordinaten in Weltkoordinaten. EDIT: Das was plenz möchte müsste eigentlich auch einfach anhand der Gyroskopdaten möglich sein. Quote Link to comment Share on other sites More sharing options...
borg Posted June 7, 2012 at 10:54 AM Share Posted June 7, 2012 at 10:54 AM So, nächster Versuch . Sorry, irgendwas klappt mit dem Programm nicht. Nach "Press key to exit" tut sich überhaupt nichts, erst nach dem Tastendruck kommt einmal "x: 0, y: 0, z:0". Der Code ist ja an sich verständlich, ich kann den Fehler nicht finden. UID angepasst? Quote Link to comment Share on other sites More sharing options...
borg Posted June 7, 2012 at 11:04 AM Share Posted June 7, 2012 at 11:04 AM In meiner Vorstellung gibt es zwei Koordinatensysteme das des Bricks mit den x,y,z Achsen so wie sie auf dem brick aufgedruckt sind und das Äußere also die Welt mit Nord-Süd (NS), Ost-West (OW) und dem gefühlten Unten-Oben (UO). Also du hast einmal das Koordinatensystem was die Quaternionen standardmäßig ausgeben. Die "Nullstellung" kannst du einfach suchen indem du dir die Quaternionen ausgeben lässt und guckst wo 0, 0, 0 rauskommt. Das IMU Brick "aufm Kopf" halten und USB Stecker 45° von Norden nach rechts, so ungefähr. Dieses Koordinatensystem ist aber nicht wichtig, da muss man nicht drin rechnen. Das "Weltkoordinatensystem" hab ich jetzt in dem Beispiel "base system" genannt. Dazu speicherst du einfach die Quaternionen an der Stelle wo du die 0, 0, 0 Position haben willst und multiplizierst die dann immer mit dem konjugierten der Quaternionen die du bekommst. Wo für dich unten/oben ist und auch wo die Himmelsrichtungen sind ist ja abhängig davon wie du die IMU einbaust! Aber wie gesagt, die Umrechnung dafür ist nur eine Quaternionen Multiplikation. Wie man dann zu unabhängigen Winkeln kommt ist auch in dem Beispiel drin. Echte Eulerwinkel (die man nacheinander Anwenden kann um zurück zum Nullpunkt zu kommen) gibt es mit der getOrientation Funktion. IMO sollten damit jetzt schon die meiste notwendige Mathematik abgedeckt sein . Edit: Eins noch: Wie man von Quaternionen zu Rotationsmatrizen kommt (z.B. zur Darstellung in Opengl/DirectX oder zur Berechnung von Gimbal Lock freien Winkel ohne Quaternionen) ist in der API Dokumentation zu den jeweiligen Sprachen beschrieben! Quote Link to comment Share on other sites More sharing options...
Plenz Posted June 7, 2012 at 12:21 PM Author Share Posted June 7, 2012 at 12:21 PM UID angepasst? Hüstel... ohne korrekte UID käme gleich am Anfang eine fette Fehlermeldung Quote Link to comment Share on other sites More sharing options...
borg Posted June 7, 2012 at 12:49 PM Share Posted June 7, 2012 at 12:49 PM Habs gerade nochmal getestet, bei mir funktionierts. D.h. der Callback kommt genau einmal? Funktionieren Callbacks denn im Allgemeinen bei dir? Wenn du das Beispiel mal soweit verkleinerst das nur noch die Callbackperiode und der Callback gesetzt wird, gehts dann? Geht das Beispiel aus der Doku: http://www.tinkerforge.com/doc/Software/Bricks/IMU_Brick_Python.html#imu-brick-python-examples? Quote Link to comment Share on other sites More sharing options...
Plenz Posted June 7, 2012 at 08:33 PM Author Share Posted June 7, 2012 at 08:33 PM Sorry, ich hab jetzt keine Lust auf Debuggen. Bisher ging jedenfalls alles. Mein Programm, das ich von dem Callback-Beispielprogramm abgeleitet habe, funktioniert nach wie vor. Jedenfalls habe ich jetzt noch mal mit meinem Programm zwei Tests gemacht, wieder einmal waagerecht und einmal um 45° gekippt, und dabei jeweils langsam um 360° rotiert. Etwa alle 5° habe ich x, y, z, w abgespeichert, in Excel übertragen und dort die Formeln eingesetzt. Hier angefügt die Ergebnisse, schön mit Diagrammen dargestellt. Man sieht: keine der Formeln rechnet irgend etwas heraus. Wenn der IMU-Brick gekippt ist, ändern sich bei einer einfachen Drehung sämtliche Winkel. Deshalb noch mal zurück nach oben zu meinem Eintrag mit den Screenshots vom Brick Viewer. Ich habe das dumpfe Gefühl, das in der grafischen Darstellung des IMU-Bricks meine gesuchten Formeln stecken, denn egal wie man den IMU-Brick auf dem Tisch rotiert, das Bild stellt immer "IMU-Brick ist 45° zur Seite gekippt" dar. Also muss es doch irgend eine Formel geben, die ich in meine Excel-Tabelle einfügen kann und die mir in jeder Zeile diese 45° errechnet.IMU_Test.xls Quote Link to comment Share on other sites More sharing options...
ROSEDOLA Posted June 8, 2012 at 10:37 AM Share Posted June 8, 2012 at 10:37 AM Also, nachdem ich nun wieder mal Zeit gefunden habe, mit der IMU zu "spielen" komme ich nun "scheinbar" zu einem "ersten" brauchbaren Ergebnis. Zielsetzung war: Erkennen von Roll, Pitch und Yaw (in einem Flugzeug) - getestet habe ich bisher nur am Schreibtisch mit Drehen, usw.... Der Kurs, errechnet aus dem Magnetfeld, ist noch nicht "Tilt-Compensated", was aber zwingend notwendig ist: Init der IMU imu.set_convergence_speed 250 sleep 5 imu.set_convergence_speed 5 q = [] q = imu.get_quaternion base_x = q[0] base_y = q[1] base_z = q[2] base_w = q[3] Konjugation x = -x y = -y z = -z Und die Winkel: x_angle = Math.atan2(2*y*z - 2*x*w, w*w + z*z - x*x - y*y)*180/Math::PI + 180 y_angle = Math.atan2(2*w*y + 2*x*z, w*w + z*z -x*x - y*y)*180/Math::PI + 180 z_angle = Math.atan2(-w*y + x*y + y*x - w*w, w*w + y*y - z*y - x*x)*180/Math::PI + 180 Diese Formeln stammen aus dem Forum, nicht von mir.... Ich werde am WE oder Anfang der Woche mal einen Flug machen und es testen. Das Brick liegt mit LED's nach oben auf einem MasterBrick gesteckt. Das IMU Brick hängt sich des öfteren auf, wenn ich dort ein lCD Prickelt einstöpsle... Code ist Ruby - wenn das nun klappt, werde ich mal nach IOS wechseln... Gruss, Dirk Quote Link to comment Share on other sites More sharing options...
borg Posted June 8, 2012 at 12:13 PM Share Posted June 8, 2012 at 12:13 PM @Plenz: Das neue Beispielprogramm tut was du möchtest, ziemlich sicher. Edit: @ROSEDOLA: Für dich könnte das neue Beispiel auch interessant sein: http://www.tinkerforge.com/doc/Hardware/Bricks/IMU_Brick.html#how-to-get-angles-that-are-independent zumindest die Berechnung von z_angle Quote Link to comment Share on other sites More sharing options...
ROSEDOLA Posted June 8, 2012 at 12:48 PM Share Posted June 8, 2012 at 12:48 PM @borg Das hatte ich in Ruby getestet. Leider komme ich damit überhaupt nicht weiter.... Gruss, Dirk Quote Link to comment Share on other sites More sharing options...
borg Posted June 8, 2012 at 02:40 PM Share Posted June 8, 2012 at 02:40 PM @ROSEDOLA: Oh, das sehe ich ja jetzt erst, dein Ruby Code tut ja schon genau das gleiche . Aber deine Formeln für x,y,z angle entsprechen irgendwie nicht denen die ich hab: x_angle = int(math.atan2(2.0*(y*z - w*x), 1.0 - 2.0*(x*x + y*y))*180/math.pi) y_angle = int(math.atan2(2.0*(x*z + w*y), 1.0 - 2.0*(x*x + y*y))*180/math.pi) z_angle = int(math.atan2(2.0*(x*y + w*z), 1.0 - 2.0*(x*x + z*z))*180/math.pi) Quote Link to comment Share on other sites More sharing options...
ROSEDOLA Posted June 8, 2012 at 03:10 PM Share Posted June 8, 2012 at 03:10 PM Die Formeln habe ich aus dem Forum / oder wars ne frühere Version der IMU Docu... ? Die für "z" ist verschwunden.... Im engl. Forum nach IMU Values suchen. Müssten von Dir gewesen sein... Gruss, Dirk Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.