7

I need the angular velocity expressed as a quaternion for updating the quaternion every frame with the following expression in OpenCV:

q(k)=q(k-1)*qwt;

My angular velocity is

Mat w;  //1x3

I would like to obtain a quaternion form of the angles

Mat qwt;   //1x4

I couldn't find information about this, any ideas?

Mar de Romos
  • 719
  • 2
  • 9
  • 22
  • 1
    A quaternion represents a rotation or an orientation. The angular velocity is the derivative of it. It is unclear what you are trying to do. – Ali Aug 21 '12 at 11:40
  • 3
    I guess he wants to express the angular velocity as a qaternion to update the quaternion value as this product: q(k)=q(k-1)*qwt – Jav_Rock Aug 21 '12 at 11:44
  • 1
    Being qwt the angular velocity expressed as a quaternion – Jav_Rock Aug 21 '12 at 11:44
  • Yes, thats it! I want to update quaternion value each frame using the angular velocity. – Mar de Romos Aug 21 '12 at 11:46
  • 2
    Alright, then if you use angular velocity each frame be careful because w should be multiplied by time between frames. – Jav_Rock Aug 21 '12 at 11:51

3 Answers3

6

If I understand properly you want to pass from this Axis Angle form to a quaternion.

As shown in the link, first you need to calculate the module of the angular velocity (multiplied by delta(t) between frames), and then apply the formulas.

A sample function for this would be

// w is equal to angular_velocity*time_between_frames
void quatFromAngularVelocity(Mat& qwt, const Mat& w)
{
    const float x = w.at<float>(0);
    const float y = w.at<float>(1);
    const float z = w.at<float>(2);
    const float angle = sqrt(x*x + y*y + z*z);  // module of angular velocity

    if (angle > 0.0) // the formulas from the link
    {
        qwt.at<float>(0) = x*sin(angle/2.0f)/angle;
        qwt.at<float>(1) = y*sin(angle/2.0f)/angle;
        qwt.at<float>(2) = z*sin(angle/2.0f)/angle;
        qwt.at<float>(3) = cos(angle/2.0f);
    } else    // to avoid illegal expressions
    {
        qwt.at<float>(0) = qwt.at<float>(0)=qwt.at<float>(0)=0.0f;
        qwt.at<float>(3) = 1.0f;
    }
}
Martin Valgur
  • 5,793
  • 1
  • 33
  • 45
Jav_Rock
  • 22,059
  • 20
  • 123
  • 164
  • 1
    Could it be you have made a mistake in the following line? `qwt.at(0)=qwt.at(0)=qwt.at(0)=0.0f;` You set the same component over and over again. – Tara Jul 23 '17 at 00:21
4

Almost every transformation regarding quaternions, 3D space, etc is gathered at this website.

You will find time derivatives for quaternions also.

I find it useful the explanation of the physical meaning of a quaternion, which can be seen as an axis angle where

a = angle of rotation
x,y,z = axis of rotation.

Then the conversion uses:

q = cos(a/2) + i ( x * sin(a/2)) + j (y * sin(a/2)) + k ( z * sin(a/2))

Here is explained thoroughly.

Hope this helped to make it clearer.

Carlos Cachalote
  • 763
  • 3
  • 9
  • 19
2

One little trick to go with this and get rid of those cos and sin functions. The time derivative of a quaternion q(t) is:

dq(t)/dt = 0.5 * x(t) * q(t)

Where, if the angular velocity is {w0, w1, w2} then x(t) is a quaternion of {0, w0, w1, w2}. See David H Eberly's book section 10.5 for proof

RichardBruce
  • 641
  • 2
  • 10
  • 19