Jump to content

IMU 3.0: Unterschiedliche Wertebereiche der Euler-Winkel pro Achse, Roll-Winkel zwischen 0 und 360 Grad gesucht


Recommended Posts

Geschrieben

Hallo TinkerUnity

Ich verwende ein IMU 3.0 Bricklet für die Bestimmung einer Rotation um eine Achse. Dabei benötige ich einen Wert zwischen ]0, 360[ Grad.

Aktuell versuchte ich die Rotation um die Y-Achse (Roll-Winkel) zu nutzen (aus konstruktiven Gründen). Da musste ich feststellen, dass der Wertebereich des ausgegebenen Euler-Winkels sich zwischen ]-90, +90[ bewegt. Das irritiert mich sehr. Vor allem kann ich so die Auslenkung nicht eindeutig bestimmen.

Dann habe ich die beiden anderen Achsen noch angesehen und habe die folgenden Wertebereiche erhalten:

* Z-Achse (Heading): ]0, 360[

* X-Achse (Pitch): ]-180, +180[

* Y-Achse (Roll): ]-90, +90[

Aus gewissen Aspekten kann ich diese Bereiche verstehen (Flugzeug, Copter). Leider passt dies aber nicht für meine Anwendung. Leider kann ich aus konstruktiven Gründen nur die beiden Achsen X und Y verwenden (Pitch und Roll).

Frage:

* Gibt es eine Möglichkeit, den Roll-Winkel im Bereich ]0, 360[ Grad trotzdem zu berechnen? Aus den Quaternionen?

Leider übersteigt das meine Fähigkeiten bei weitem. Falls jemand eine konkrete Umsetzung hätte, wäre ich sehr dankbar.

Mit den besten Grüssen,

Yvo

 

Geschrieben

Salut Backdraft007

Ich habe ein Foto des aufbaus gemacht. Allenfalls besser als eine Skizze. Ich hoffe, es ist so gut erkennbar:

  • In der Mitte befindet sich die Drehachse. Um diese kann in beide Richtungen gedreht werden.
  • Auf dem Schild sind die Sollwerte beschrieben:
    • Unten 0 Grad
    • Oben 180 Grad
    • Links und Recht die 90 und 270 Grad
  • Unten auf dem Stab ist die IMU montiert. Wie beschrieben, kann diese nur in so montiert werden:
    • Die IMU wird auf der Y-Achse rotiert.
    • Die weiteren Rotationen (X- und Z-Achse) interessieren in diesem Setup nicht.

Erklärt diese Skizze die Situation?

Freue mich auf alle Inputs,

Yvo

ImuVersuchsaufbau.png.930e950f22389c8184336ea38e9bef11.png

Geschrieben

Salut Backdraft007

Vielen Dank für den Link. Ich muss mir das gleich im Detail reinziehen.

Ich habe noch versucht, mit dem kurzen Video die Drehung zu zeigen.

Grundsätzlich ist es eine "simple" Fragestellung:

  • Die montierte IMU wird über die Rotation ausgelenkt.
  • Dies in einem vollen Kreis, in welchem die Position in einem Bereich von ]0, 360[ Grad gemessen werden muss.

Eventuell kommt Dir da noch etwas in den Sinn.

Merci vielmals,

Yvo

 

Geschrieben

@Backdraft007 noch eine Frage zur suppertollen Webseite, welche Du mir angegeben hast. Merci nochmals dafür:

  • Dort wird eingangs beschrieben, dass es bei den Ausführungen darum geht, die Winkel für die DIN70000 auszugeben.

Da verstehe ich, dass bei einem (Strassen-)Fahrzeug kein Interesse an einem Roll-Winkel zwischen ]0, 360[ Grad besteht.

Frage:

  • Könnte dies ein Grund sein, dass die Winkel / Formelapparate keinen Roll-Winkel zwischen ]0, 360[ Grad ausgeben?

Das wäre allenfalls einen neuen Hinweis für die weitere Suche.

Mit den besten Grüssen,

Yvo

Geschrieben

@Backdraft007 Ich habe mich ausführlich mit der von Dir angegebenen Webseite befasst. Und konnte zum Glück was herleiten, das für mich tauglich ist. Und ich habe noch das Glück, dass ich das Bricklet doch um 90 Grad drehen kann und die X-Achse nach "vorne" guckt. So kann ich mit dieser Achse anstelle der Y-Achse arbeiten.

Die restliche Mathe um die Quaternionen musst ich leider  aufgeben.

Die Funktionen für die Berechnung der Rotation um die X-Achse im gewünschten Bereich von ]0, 2Pi[ sehen jetzt so aus:

def normQ(q):
    '''
    Calculates the normalized Quaternion
    a is the real part
    b, c, d are the complex elements
    '''
    # Source: Buchholz, J. J. (2013). Vorlesungsmanuskript Regelungstechnik und Flugregler.
    # GRIN Verlag. Retrieved from http://www.grin.com/de/e-book/82818/regelungstechnik-und-flugregler
    # https://www.cbcity.de/tutorial-rotationsmatrix-und-quaternion-einfach-erklaert-in-din70000-zyx-konvention

    a, b, c, d = q
 
    # Absolute value used for the normalization.
    Z = np.sqrt(math.pow(a, 2) + math.pow(b, 2) + math.pow(c, 2) + math.pow(d, 2))
 
    return np.array([a / Z, b / Z, c / Z, d / Z])

def Q2Eul(q):
    '''
    Calculates the Euler Angles from Quaternion
    a is the real part
    b, c, d are the complex elements
    '''
    # Source: Buchholz, J. J. (2013). Vorlesungsmanuskript Regelungstechnik und Flugregler.
    # GRIN Verlag. Retrieved from http://www.grin.com/de/e-book/82818/regelungstechnik-und-flugregler
    # https://www.cbcity.de/tutorial-rotationsmatrix-und-quaternion-einfach-erklaert-in-din70000-zyx-konvention
    '''
    Getting the quaternion normalized.
    Remarks:
    * In case of Tinkerforge-IMU, the values given by the sensor have to be divided by 16383 (14 bit).
      * After the division, the values are already within the range ]-1, +1[.
      * Principally, no normalization requested.
    * To have a generic, function, the normalization of the quaternion is done in any case.
    '''
    q = normQ(q)
 
    a, b, c, d = q
 
    z = np.arctan2(2.0 * (b * c + a * d), (math.pow(a, 2) + math.pow(b, 2) - math.pow(c, 2) - math.pow(d, 2)))
    y = np.arcsin(2.0 * (a * c - b * d))
    x = np.arctan2(2.0 * (c * d + a * b), -1 * (math.pow(a, 2) - math.pow(b, 2) - math.pow(c, 2) + math.pow(d, 2))) * -1
    x += math.pi
 
    return np.array([z, y, x])

def cb_all_data(acceleration, magnetic_field, angular_velocity, euler_angle, quaternion,
                linear_acceleration, gravity_vector, temperature, calibration_status):
    '''
    Reduction of the values given by the sensor into the usual range of -1.0 to +1.0 for quaternions.
    Requested by the IMU-bricklet of Tinkerforge:
    * Division of the return values by 16383 (14 bit).
    '''
    q = np.array(
        [quaternion[0] / 16383.0, 
         quaternion[1] / 16383.0, 
         quaternion[2] / 16383.0, 
         quaternion[3] / 16383.0])
    q2EulResult = Q2Eul(q)

    rotationX = q2EulResult[2]
    print("X-axis by quaternion (radians): " + str(round(rotationX, 2)))
    print("X-axis by quaternion (degrees): " + str(round(math.degrees(rotationX), 2)))

So kriege ich aktuell die von mir benötigten Werte korrekt raus. Die Rotationen um die Y- und Z-Achse kann ich (zum Glück) ignorieren.

Nochmals vielen Dank für den super Link.

Mit den besten Grüssen,

Yvo

Join the conversation

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

Gast
Reply to this topic...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Clear editor

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

×
×
  • Neu erstellen...