Search code examples
quaternionsmyo

Myo bracelet; How go from quaternion to forearm direction unit vector?


I am doing a project with a myo bracelet. The bracelet uses quaternions to track it's orientation. What I want is a vector that points in my forearms direction without orienation, i.e. I only want a unit vector that represents my forearm. Is this possible and does anyone know how to do this?

I have tried to perform quaternion multiplication by P' = QPQ^-1, by following the instructions on this site Maths - Transforming Vectors with Quaternions` but I don't get this to work. I suspect that this is because the quaternion output from the Myo bracelet is not one single rotation but a continuously changing orientation/rotation as I move my arm/the bracelet.

Basically the data that I get from the Myo is on the form of [X,Y,Z,W] and this is changing as I move my arm. I would highly appreciate if anybody could be kind to help me out a bit

Cheers, // hjalle


Solution

  • It sounds like you're trying to get the Euler angles from the quaternion, so this reference might be a better starting point. The hello-myo example from the Myo SDK documentation (part of the SDK download here) uses the following code:

    // Calculate Euler angles (roll, pitch, and yaw) from the unit quaternion.
    float roll = atan2(2.0f * (quat.w() * quat.x() + quat.y() * quat.z()), 1.0f - 2.0f * (quat.x() * quat.x() + quat.y() * quat.y()));
    float pitch = asin(max(-1.0f, min(1.0f, 2.0f * (quat.w() * quat.y() - quat.z() * quat.x()))));
    float yaw = atan2(2.0f * (quat.w() * quat.z() + quat.x() * quat.y()), 1.0f - 2.0f * (quat.y() * quat.y() + quat.z() * quat.z()));
    

    Unrelated to the above and not sure if it'll be helpful, but if you're trying to locate the arm in the real world you'll always need a known reference or starting orientation, then compare all of the following measurements to that. With Myo this is typically done by having the wearer put their arm in a known position and hitting a calibration button. Sometimes there are more clever ways of doing this but it depends on the application. Once you have the reference you would subtract it from the future measurement to get the real orientation, essentially: orientationReal = orientationMeasured - orientationReference You'll typically want to do this calculation in quaternion format first (see Gimbal lock) but depending on your application maybe euler angles would be OK.