2017-07-15 1 views
1

Ich bin fast in der Lage, die Bewegung eines Objekts in 2D-Raum in Unity3D (ähnlich einer Cursorbewegung) zu steuern, mit rohen Gyroskopdaten von Thalmic Myo Armband.Quaternion Rotation für Gyroskop Frame-of-Referenz Konvertierung in Unity 3D

Ich habe versucht, die Gyroskopdaten von ihren eigenen Achsen/Bezugssystem auf den Weltrahmen der Referenz durch eine Reihe von Rotationen und Transformationen zu transformieren.

Alles wird kompiliert, bis auf einen einzigen Fehler, und wenn dieser Fehler ignoriert wird, bewegt sich das Objekt, während sich der Kreisel dreht, aber die endgültigen x-/y-Koordinaten sind in die falsche Richtung verschoben.

Bitte korrigiert mich wenn ich falsch liege, aber mein general approach wäre:

  1. Erhalten Gyroskop Vector
  2. drehen sie durch Orientierung Quaternion (von Beschleunigungsmesser), um es auszurichten zu world space
  3. Erhalten Sie normalisierte Quaternion, die den richtigen Vektor dreht
  4. Drehen Sie ausgerichteten Vektor aus (2) von diesem Quaternion eine kompensierte Vector (-Z) Komponente von Vector aus (2) und (y) Komponente kompensierte Vektor von (4) erhält die gewünschten dx und dy-Werte geben

Hier ist mein Ansatz : Rufen die Konvertierungsfunktion, Eingangskreiseldaten, aktuelle Orientierung und X-Richtung (ob das Band das Handgelenk oder umgekehrt zugewandt ist):

Vector2 dxdy = gyroConversion (thalmicMyo.gyroscope, myo.transform.rotation, thalmicMyo.xDirection); 

transform.Translate (dxdy [0], dxdy [1], 0, Space.World); 

die gyroConversion Funktion:

Vector2 gyroConversion (Vector3 gyroData, Quaternion orientation, object xdir) { 

    // Convert gyro data from the gyroscope's frame of reference to the world frame of reference. 

    // Rotate gyroData by orientation quaternion. 
    Vector3 gyroWorldData = orientation * gyroData; 

    // Check which direction the armband is facing. 
    if (xdir.Equals(Thalmic.Myo.XDirection.TowardWrist)) { 
     Vector3 forwardSource = new Vector3 (1, 0, 0); 
    } 

    else { 
     Vector3 forwardSource = new Vector3 (-1, 0, 0); 
    } 

    Vector3 right = Vector3.Cross(forward, new Vector3 (0, 0, -1)); 
    Vector3 up = new Vector3 (0, 1, 0); 

    Quaternion yQuat = Quaternion.FromToRotation(right, up); 

    float m = Mathf.Sqrt(yQuat.w * yQuat.w + 
     yQuat.x * yQuat.x + 
     yQuat.y * yQuat.y + 
     yQuat.z * yQuat.z); 

    yCompNorm = new Quaternion (yQuat.w/m, yQuat.x/m, yQuat.y/m, yQuat.z/m); 

    Vector3 gyroCompensated = yCompNorm * gyroWorldData; 

    Vector2 coordinates = new Vector2 (-gyroWorldData.z, gyroCompensated.y); 

    return coordinates; } 

Hinweis: ForwardSource verursacht einen Fehler, der mir sagt, dass es "nicht im aktuellen Kontext existiert", aber wenn eine einzige ForwardSource-Definition anstelle des If-Else-Paares existiert, funktioniert es gut und so kenne ich das gewünschte Objekt bewegt sich tatsächlich, nur wirklich komisch. Es scheint, als ob meine Links-Rechts-Bewegungen auf dem Gyroskop in Unity eine Aufwärts-Abwärts-Bewegung erzeugen.

Es ist wahrscheinlich ein Problem mit den Rotationen, aber ich sehe nicht wo.

Antwort

0

Es scheint, als ob meine Links-Rechts-Bewegungen auf dem Gyroskop in Unity eine Aufwärts-Abwärts-Bewegung erzeugen.

Nicht ganz sicher, ob dies das Problem ist, aber der Kreisel Input.gyro.attitude Sensorwert wird in Rechtshändige Koordinaten zurück während Unity das Linkshänder Koordinaten System verwendet. Sie müssen den Gyro (Rechtshänder-Koordinaten) in Linkshänder-Koordinaten umwandeln, bevor Sie versuchen, ein Objekt zu bewegen.

private static Quaternion GyroToUnity(Quaternion q) 
{ 
    return new Quaternion(q.x, q.y, -q.z, -q.w); 
} 

...

Quaternion convertedValue = GyroToUnity(Input.gyro.attitude); 

Jetzt können Sie die convertedValue Variable für andere Berechnungen verwenden oder ein Objekt/Kamera zu bewegen.