Quaternion => Euler

  • VB.NET

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von Goof.

    Quaternion => Euler

    Hallo zusammen,

    wie kann ich Quaternion nach Euler umrechnen?

    Quellcode

    1. Dim qw As Double = txtbox_Quat_W.Text
    2. Dim qx As Double = txtbox_Quat_X.Text
    3. Dim qy As Double = txtbox_Quat_Y.Text
    4. Dim qz As Double = txtbox_Quat_Z.Text
    5. Dim qy2 As Double = qy * qy
    6. Dim qz2 As Double = qz * qz
    7. Dim qw2 As Double = qw * qw
    8. txtbox_gamma.Text = (Math.Atan2(2 * (qx * qy + qz * qw), 1 - 2 * (qy2 + qz2))) * 180 / Math.PI
    9. txtbox_beta.Text = -(Math.Asin(2 * (qx * qz - qw * qy))) * 180 / Math.PI
    10. txtbox_alpha.Text = 180 - (Math.Atan2(2 * (qx * qw + qy * qz), 1 - 2 * (qz2 + qw2))) * 180 / Math.PI


    Irgendwo hab ich einen Fehler drin. Der Code funktioniert bis auf einige Ausnahmen. Wo habe ich den Denkfehler?

    Vielen Dank
    Goof
    Schalt bitte zunächst mal "Option Strict" auf ON. Als Resultat wirst du einige Fehler erhalten, die es gilt zu beheben. Wenn dann dein Problem immer noch besteht, melde dich nochmal.
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.
    @Arby Jou.
    @Goof Dann trenne zwischen Daten und GUI und bau Dir eine statische Methode, die Koordinaten von a nach b sowie von b nach a umrechnet.
    Das Ergebnis zeigst Du dann in der GUI an.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Na jetzt habe ich zumindest einige Fehler gefunden:

    Quellcode

    1. Dim qw As Double = CDbl(txtbox_Quat_W.Text)
    2. Dim qx As Double = CDbl(txtbox_Quat_X.Text)
    3. Dim qy As Double = CDbl(txtbox_Quat_Y.Text)
    4. Dim qz As Double = CDbl(txtbox_Quat_Z.Text)
    5. Dim qx2 As Double = qx * qx
    6. Dim qy2 As Double = qy * qy
    7. Dim qz2 As Double = qz * qz
    8. Dim qw2 As Double = qw * qw
    9. '####
    10. Dim unit As Double = qx2 + qy2 + qz2 + qw2
    11. Dim test As Double = qx * qy + qz * qw
    12. If test > 0.499 * unit Then
    13. txtbox_gamma.Text = CType(2 * Math.Atan2(qx, qw), String)
    14. txtbox_beta.Text = CType(Math.PI / 2, String)
    15. txtbox_alpha.Text = CType(0, String)
    16. Exit Sub
    17. End If
    18. If test < -0.499 * unit Then
    19. txtbox_gamma.Text = CType(-2 * Math.Atan2(qx, qw), String)
    20. txtbox_beta.Text = CType(-Math.PI / 2, String)
    21. txtbox_alpha.Text = CType(0, String)
    22. Exit Sub
    23. End If
    24. '####
    25. txtbox_gamma.Text = CType((Math.Atan2(2 * (qx * qy + qz * qw), 1 - 2 * (qy2 + qz2))) * 180 / Math.PI, String)
    26. txtbox_beta.Text = CType(-(Math.Asin(2 * (qx * qz - qw * qy))) * 180 / Math.PI, String)
    27. txtbox_alpha.Text = CType((Math.Atan2(2 * (qx * qw + qy * qz), 1 - 2 * (qz2 + qw2))) * 180 / Math.PI, String)


    Warum wird aber der Winkel alpha falsch berechnet?

    Goof

    Goof schrieb:

    Warum wird aber der Winkel alpha falsch berechnet?
    Wweil Du die Umrechnung wohl falsch implementiert hast.
    Woher hast Du den von Dir implementierten Algotithmus?
    ====
    Meinen Rat mit den statischen Methoden hast Du ignoriert, hätte ich auch gemacht.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Also ich mal folgendes benutzt
    Spoiler anzeigen

    VB.NET-Quellcode

    1. '***********Umrechnung der Quaternionen zu Euler-Winkel*******direkt in Degree************************
    2. Public Shared Sub quat2euler(ByVal qx As Double, ByVal qy As Double, ByVal qz As Double, ByVal qw As Double, ByRef roll As Double, ByRef pitch As Double, ByRef yaw As Double)
    3. 'Formel zur Umwandlung quadertionen zu Euler-Winkel nach wikipedia
    4. ' https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
    5. '****************************
    6. Dim ysqr = qy * qy
    7. ' roll (x-axis rotation)
    8. Dim t0 = +2.0 * (qw * qx + qy * qz)
    9. Dim t1 = +1.0 - 2.0 * (qx * qx + ysqr)
    10. roll = Atan2(t0, t1)
    11. ' pitch (y-axis rotation)
    12. Dim t2 = +2.0 * (qw * qy - qz * qx)
    13. t2 = If(t2 > 1.0, 1.0, t2)
    14. t2 = If(t2 < -1.0, -1.0, t2)
    15. pitch = Asin(t2) 'pitch
    16. 'yaw(z-axis rotation) von 'von http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/
    17. Dim test = qx * qy + qz * qw
    18. yaw = Asin(2 * test) 'rotation about z axis
    19. If (test > 0.499) Then 'singularity at north pole
    20. pitch = 2 * Atan2(qx, qw) 'rotation about y axis
    21. yaw = Math.PI / 2 'rotation about z axis
    22. roll = 0 'Rotation about x axis
    23. End If
    24. If (test < -0.499) Then '// singularity at south pole
    25. pitch = -2 * Atan2(qx, qw)
    26. yaw = -Math.PI / 2
    27. roll = 0
    28. End If
    29. '*****************
    30. 'Umrechnung von rad in deg
    31. Dim faktor = 57.29578 ' 1 rad entspricht 57,29578°
    32. roll = faktor * roll
    33. pitch = pitch * faktor
    34. yaw = yaw * faktor
    35. End Sub
    36. '**********************ENDE DER Umrechnung von Quaternionen zu Euler Winkeln*******************************************

    Das funktionierte damals, habe keine Garantie

    Vielleicht musst Du die Quaternionen noch normieren, die müssen qx+qy+qz+qw=1 ergeben.
    Die sind leider nicht immer normiert, warum auch immer.
    X: -0,963527685163018 ; Y:0,18526383652391; Z:0,1554548168977; W:0,114566621247819

    Sollte -190; 20; 20 ergeben. Es kommt aber 170; 20; 20 raus.

    Auch bei 120; 160; 170 kommt X: -0,477423325132695; Y: 0,192727303262308; Z: 0,0121613065941235; W: 0,857190327650985 wiederum ein falscher Wert heraus: -59,9999999999997; 19,9999999999999; -10
    Warum sollte man dass denn wollen?
    Natürlich könntest du immer hin gehen und bei negativ Zahlen 360° drauf addieren. Ich versteh nur nicht warum man das tun sollte? Wenn man die in nen sin/cos/tan/.. packt kommt am ende genau dasselbe raus. In einem Fall dreht man sich halt im Uhrzeigersinn und im anderen Fall gegen den Uhrzeigersinn, aber in beiden Fällen kommt man auf dem Kreis an derselben stelle an.
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    ich habe vergessen, dass es wichtig ist welche Orientierung Du verwendest. Je nach Orientierung kommen andere Ergebnisse herraus.
    Dazu kannst Du zum Beispiel hier quaternions.online/ Deine beiden Fälle eingeben und die Orientierung ändern. Dann siehst Du zum Teil unterschiedliche Ergebnisse.

    Mit Orientierung ist gemeint, dass Du zuerst um bestimmte Achsen drehst, zum Beispiel erst um x dann um y und zum Schluss um z.
    jvbsl hat das im vorherigen Post geschildert. Es gibt mehrere Möglichkeit wie man die Achsen verdrehen kann, um an das selbe Ziel zu kommen. Oft steht in der Dokumentation welche Orientierung beim Sensor o.ä. verwendet wird. Ansonsten frag beim Hersteller.