LESSON

Quaternions representation of rotation in 3D

Transcript

In high school or Engineering Maths, you’ve probably come across the concept of a complex number. A number has got two components, a real component and an imaginary component. The imaginary component is a real scalar B multiplied by the imaginary number i, i being the square root of -1. We can extend this concept to what’s called a hypercomplex number. Now, instead of having just one imaginary number i, we have imaginary numbers i, j, and k. They are each the square root of -1 and their product is equal to -1. So, the hypercomplex number has got one real part and three imaginary parts. Hypercomplex numbers are typically written as a scalar plus a vector, s plus v.

The concept of hypercomplex numbers can be traced back to the Irish mathematician, William Hamilton. The story goes that one day, he was walking along the Canal in Dublin and the key equation, i2 = j2 = k2 = ijk = -1 came in to his brain. And, he carved the equation in to a stone on the wall of the bridge. And, there is today a plaque on this particular bridge which commemorates this flash of genius and inspiration.

The hypercomplex number is the basis of a mathematical object that we call a quaternion. I denote a quaternion as a Q with a little circle above it. So, we write it at s + v. S is a real scalar and v is a vector representing the complex part of this number.

Quaternions are often written in this form as well where we have s and then inside angle brackets, we have the three elements of the vector part, the three imaginary parts of the quaternion. There are quite a few different ways of writing quaternions. This is the way that I will use in this lecture and also the way that the robotics Toolbox represents a quaternion in MATLAB. Just as we can determine the magnitude or length of a vector, we can determine the magnitude or length of a quaternion and it’s the square root of the sum of the four numeric elements of the quaternion, it’s real part and the three imaginary parts.

Now, we get to what’s called a unit quaternion and this is a quaternion whose magnitude is equal to 1. Unit quaternions are particularly useful because we can use them to encode rotation in three dimensional space. A unit quaternion has a lot of similarities to the angle and axis representation that we discussed in the last section. The real part of the unit quaternion is equal to the cosine of half the rotation angle and the rotation axis which I have denoted here by n-hat is related to the vector part of the quaternion by this relationship which involve sine of half the rotation angle. I can compound two unit quaternions. Just as we can compound two rotation matrices, I can compound two quaternions and it’s done by using this, what’s called the Hamiltonian product rule.

So, quaternion 1 rotates me from frame A to frame B. Quaternion 2 rotates me from frame B to frame C, then, the product is the rotation from frame A to frame C. And, I can compute the inverse of a quaternion. So if I use a quaternion to rotate me from frame A to frame B, the inverse is quite simple. It’s just the negation of the vector part of the quaternion.

Once again, I’m going to create a fairly arbitrary rotation matrix. Going to start with some Euler angles, convert them to rotation matrix 0.1, 0.2, 0.3, just for the purpose of illustration. Here we have a rotation matrix.

Now, I’m going to create a quaternion and I use the quaternion class and I parse in as an argument a rotation matrix. And, the result is a quaternion object which we can see in our workspace. Now, the quaternion has got a real part and an imaginary part, which is indicated inside the angle brackets. I’m going to park the quaternion into a permanent variable called Q and let’s look at what we can do with this quaternion object in MATLAB.

One of the things that I can do is I can plot this quaternion and look at the orientation and it behaves just like the trplot function that we looked at earlier. I can compute the inverse of the quaternion, and here it is here, and we can see that the real part of the quaternion remains unchanged, but the vector part is negated. If I multiply the quaternion by its inverse, the result is the null quaternion. This has got a vector component equal to 0. So this indicates a 0 rotation. I can also compute that using the division operator in MATLAB. So, if I take a quaternion and effectively divide it by the quaternion, it’s the same as multiplying by its inverse. I once again get the zero rotation.
If I have a quaternion and I multiply it by a vector, let’s say a vector is a unit vector in the x direction and I turn it to a column vector by transposing it, then what this notation in MATLAB does is to multiply the vector by the quaternion. Effectively, it rotates the vector. Finally, I can do an example to illustrate interpolation. If I call quaternion with no arguments, it returns a quaternion corresponding to the null rotation. So, if I use MATLAB syntax like this, I take my null quaternion, interpolate it with the other quaternion I have, Q, and I parse in an argument which tells me the interpolation fraction. So, this is interpolating between the quaternion Q0, the null rotation, and the quaternion Q.

The last argument is the interpolation distance. 0 corresponds to the initial quaternion. 1 corresponds to the final quaternion. If I parse in 0, the result should be our initial quaternion. Make it 1, the result will be our final quaternion. And if I put in something like 0.5, this is an interpolation halfway between the initial quaternion and the final quaternion. So this is a way to interpolate rotations that are represented as quaternions.

Code

There is no code in this lesson.

The orientation of a body in 3D can also be described by a unit-Quaternion, an unusual but very useful mathematical object.

 

In the MATLAB example starting at 3:48 I use the Quaternion class.  For Toolbox version 10 (2017) please use UnitQuaternion instead.

Professor Peter Corke

Professor of Robotic Vision at QUT and Director of the Australian Centre for Robotic Vision (ACRV). Peter is also a Fellow of the IEEE, a senior Fellow of the Higher Education Academy, and on the editorial board of several robotics research journals.

Skill level

This content assumes high school level mathematics and requires an understanding of undergraduate-level mathematics; for example, linear algebra - matrices, vectors, complex numbers, vector calculus and MATLAB programming.

More information...

Rate this lesson

Average

Check your understanding

Discussion

  1. Jerry K says:

    It’s not entirely clear the MATLAB code suggested in the answer to Question 1 works with the current version of the toolbox.

    >> R=rpy2r([20, -10, 30], ‘deg’)

    followed by:

    >> Quaternion(R)

    gives me:

    Error using Quaternion (line 122)
    bad argument to quaternion constructor

    It’s not clear looking at the code and docs that there’s a constructor supporting this usage?

    1. Peter Corke says:

      Use the UnitQuaternion constructor instead, there is a note under the video which says this, I just made it bold to be hopefully more noticeable. The old Quaternion class was a mishmash of regular and unit quaternion functionality, now split into a Quaternion and UnitQuaternion classes. Only UnitQuaternions are useful for representing rotations.

  2. prasadmadhale says:

    For Q1 I used the exact formulas mentioned in the answer but I get option C as the answer. Is there a specific reason? I am using UnitQuaternion constructor as suggest in the note.

    Here’s the output:

    >> R = rpy2r([20,-10,30],’deg’)

    R =

    0.8529 -0.5213 0.0297
    0.4924 0.7841 -0.3778
    0.1736 0.3368 0.9254

    >> q = UnitQuaternion(R)

    q =

    0.94371

    1. kaogula says:

      The video is made by RTB 9.x, whose rpy2r function is in order of yaw, pitch, roll (but the documentation said roll, pitch, yaw) ,in RTB10.X the order is changed along with the documentation, roll, pitch, yaw. so I guess the right answer should be C.

      1. Peter Corke says:

        The angles are always given in the order roll, pitch then yaw. In RTB9 the default angle sequences is yaw about X, pitch about Y then finally roll about Z. In RTB10 that default sequence is different. If you are using RTB10 then you need to add the option ‘xyz’ to make it compatible with RTB9.

    2. Peter Corke says:

      In RTB9 the default angle sequences is yaw about X, pitch about Y then finally roll about Z. In RTB10 that default sequence is different. If you are using RTB10 then you need to add the option ‘xyz’ to make it compatible with RTB9.

  3. Prashant says:

    q = Quaternion( rpy2tr(0.1, 0.2, 0.3) )
    Error using Quaternion (line 122)
    bad argument to quaternion constructor

    sir this error comes everytime i enter quaternion.

    1. Prashant says:

      sorry for the question
      i have got the answer from one of the comment.
      thank you

    2. Peter Corke says:

      Hi Prashant, as I mentioned in an earlier reply to you, there are a few minor differences between RTB9 and RTB10. This is one of them. The example you give works, as in the video, for RTB9. All the videos are based on RTB9. For RTB10 use instead: q = UnitQuaternion( rpy2tr(0.1, 0.2, 0.3) )

  4. SirClems says:

    I am also a bit confused sir. Please look at my codes:

    first code:
    >> R = rpy2r(20,-10,30,’deg’,’xyz’)

    R =

    0.9254 -0.3368 -0.1736
    0.2146 0.8435 -0.4924
    0.3123 0.4184 0.8529

    >> UnitQuaternion(R)

    ans =

    0.95155

    Second code:

    0.95155

    third code:
    >> R = rpy2r(20,-10,30,’deg’)

    R =

    0.8529 -0.5213 0.0297
    0.4924 0.7841 -0.3778
    0.1736 0.3368 0.9254

    >> UnitQuaternion(R)

    ans =

    0.94371

    Please professor, help me clear my doubts.

    Thanks

    1. SirClems says:

      Third code:
      >> R = rpy2r(20,-10,30,’deg’)

      R =

      0.8529 -0.5213 0.0297
      0.4924 0.7841 -0.3778
      0.1736 0.3368 0.9254

      >> UnitQuaternion(R)

      ans =

      0.94371

      just saw that i didn’t paste it well.

      THANKS

      1. Peter Corke says:

        Sorry for the delay, I’ve been on holiday… I’ve made changes to the question (to clarify the angle order) and made the explanation (shown when the answer is incorrect) much more explicit for RTB9 and RTB10. I will make changes to other questions/explanations in this section to remedy confusion about the different toolbox versions. Thanks for pointing this out.

  5. Pratik Acharya says:

    Is there a function in the MATLAB tool to convert a Quaternion into a Rotation Matrix?

  6. Sachin Nath says:

    >> t = rpy2r(20, -10, 30, ‘xyz’)

    t =

    0.9254 -0.3368 -0.1736
    0.2146 0.8435 -0.4924
    0.3123 0.4184 0.8529

    >> UnitQuaternion(t)

    ans =

    0.95155

    I got the imaginary numbers in reverse order.

    1. Peter Corke says:

      I suspect this is related to the problem you express in all your other comments, most likely an installation problem and clash with another toolbox. See the FAQ page

      1. Sachin Nath says:

        Sir thank you for your replies for each and every question I asked, after so many trial runs in RTB 10.X I was still unable to get the right outputs so I uninstalled RTB toolbox of 10.X and installed toolbox version 9.X now I am getting the right answers, sorry for asking so many questions of similar type and thank you again for your replies.

  7. Sachin Nath says:

    So are we only describing the angle at which the frame is rotated and this frame is bound to the world frame. If yes, how to get the translational part of the frame using quaternion. Or are we describing both the rotational and translational part of the frame by using the function [ UnitQuaternian ]. Help me with this professor.

    1. Peter Corke says:

      Unit quaternions express the rotation of one frame with respect to another. They cannot express the translation between the origins of the frames.

  8. AstroPrite says:

    Thank you for the good class. Anyway, I got the answer right but with the imaginary part wrong.

    q = 95155

    Is the corresponding choice a typo?

    1. Peter Corke says:

      You probably used rpy2r as part of your calculation, check that you are doing the XYZ angle sequence.

  9. Amer says:

    Great effort, Professor peter and your wonderful QUT team.

    the solution of Q1:-

    >> rpy2r(20,-10,30, ‘xyz’)

    ans =

    0.9254 -0.3368 -0.1736
    0.2146 0.8435 -0.4924
    0.3123 0.4184 0.8529

    >> UnitQuaternion(ans)

    ans =

    0.95155

  10. Josh_Allison says:

    Hi Professor,

    I have thoroughly enjoyed these lessons and found them very helpful in my exploration of 3-D rotations.
    I was wondering if you could answer a question for me.

    I have read that a rotation matrix may be generated by finding the directional cosines of the local coordinate systems of two rigid bodies A and B e.g

    R = [ dot(Xb, Xa), dot(Yb, Xa), dot(Zb, Xa);
    dot(Xb, Ya), dot(Yb, Ya), dot(Zb, Ya);
    dot(Xb, Za), dot(Yb, Za), dot(Zb, Za) ]

    My question: Are the scalar elements of this matrix equivalent to elements of the general rotation matrix for a particular Euler angle sequence (e.g. X-Y-X) and/or for the general rotation matrix generated by the elements of a quaternion e.g. q = a + bi +cj + dk, where the rotation matrix is given by:

    R (quaternion) = [ a^2 + b^2 + c^2 + d^2, 2bc – 2ad, 2bd + 2ac; …
    2bc + 2ad, a^2 – b^2 + c^2 – d^2, 2cd – 2ab; …
    2bd – 2ac, 2cd + 2ab, a^2 + b^2 + c^2 + d^2 ]

    Many thanks,
    Professor.

  11. Kiruthik says:

    Sir, what is the name of the software you use to calculate vectors?

  12. MO. Adam says:

    Hallow Mr. Corke,
    I hope you would have time to comment on this odd results I got. I used Toolbox 10, I wrote the code perfectly after several faulty attempts. Although, when I tried to multiply the Quaternion (q) by its inverse I got an answer with e to the power -18 and – 17. Here is the code:
    R = eul2r(0.1, 0.2, 0.3)

    R =

    0.9021 -0.3836 0.1977
    0.3875 0.9216 0.0198
    -0.1898 0.0587 0.9801

    >> UnitQuaternion(R)

    ans =

    0.97517

    >> q = ans

    q =

    0.97517

    >> q.plot()
    >> inv(q)

    ans =

    0.97517

    >> q * inv(q)

    ans =

    1

    My question, is this roughly right( since e to the power -18 is trivial)? why do think I got that?
    Thanks in advance

  13. MO. Adam says:

    >> UnitQuaternion(R)

    ans =

    0.97517

    >> q = ans

    q =

    0.97517

    >> q.plot()
    >> inv(q)

    ans =

    0.97517

    >> q * inv(q)

    ans =

    1

Leave a comment