# 3 axis gimbal controller and quaternions

this question has been probably asked in different forms but please bare with me:

I'm building a three axis gimbal controller as part of my uni project. Besides the gimbal stabilization on each axis, the pitch and yaw also need to be manually controlled.

I initially used euler angles but, because of gimbal lock, as soon as the platform was pitched at 90 deg. the eulers would explode so the obvious solution to that was to switch to quaternions.

I've been reading for days on quaternions and I understand the main concept (that they describe a rotation around an arbitrary axis) but still can't grasp how I can manipulate the quaternion coming from my IMU in order to deduce my position on each axis on the body frame (as a number range vs an angle). I tried analyzing the w, x, y, z and compute them into three control inputs to stabilize the three axis but as soon as I Yaw the controller, everything changes. To note, the IMU is placed on the gimbal (measures gimbal's body frame referenced to ECI global frame).

For reference, here is my 2 axis gimbal (was using eulers). Note the IMU on the platform, staying horizontal. http://www.youtube.com/watch?v=JcftpJ7L7us

If anyone has any hints / pointers please help me out.

Kind Regards, Mihai.

## EDIT : solved my own dilema :D

so basically what I needed was to decompose my quaternion into three rotations (x,y,z) reffered to the body frame. I'm not sure if this is the right approach but works in my sim.

here is a quick insight for pitch (y) axis (quart = (w,x,y,z) ) what I did is i took my outputted q (body frame ref to ECI) and cloned it and zeroed the z component. this new was then normalized. from there I practically canceled out the yaw rotation in the main q by

newq = (q')*(cloned q)

then I repeated the above on newq but canceled x (roll) and works like a charm.

code below:

//pitch calc
float norq = sqrt( q[0]*q[0] + q[3]*q[3] );

angleq[0] = q[0]/norq;
angleq[1] = 0 ; //x
angleq[2] = 0;  //y
angleq[3] = q[3]/norq;  //z


newqangle = quatProd(quatConjugate(q),angleq);

norq = sqrt( newqangle[0]*newqangle[0]  +  newqangle[1]*newqangle[1]  );

angleq[0] =  newqangle[0]/norq;
angleq[1] = newqangle[1]/norq;  //z ; //x
angleq[2] = 0;  //y
angleq[3] = 0;

newqpitch = quatProd(quatConjugate(newqangle),angleq);


I'm just beginning to grasp the quaternion concept so if there is a better way of doing the above please let me know.

Regards, Mihai.

-
I don't know how much time you have to continue to read, but I'm aware of two books that I think are geared towards someone like you. Check out Quaternions and rotation sequences by Kuipers, and maybe Rotations, quaternions and double groups by Altmann (if you are on a budget). I wish I could help directly, but I've not yet learned how to manipulate quaternions for real-life situations :) – rschwieb Jan 11 '13 at 15:03
Hi, thanks for the quick reply :) I'll have a look for those two books. I have a general idea on how to manipulate quaternions but still not sure how to get to the final answer. I'l keep this topic updated in case I come up with the solution myself. – user56921 Jan 11 '13 at 15:20
It strikes me there should be a more rigorous way to do this. What is it you're trying to do? Decompose the quaternion into rotations about the body axes? – Muphrid Jan 11 '13 at 20:21
that's exactly what I want to accomplish :) any easier ideas that don't involve eulers ? – user56921 Jan 11 '13 at 20:27

Irrespective of the mathematical formalism used, the mechanical system would exhibit gimbal lock or "wrist flip" (it is essentially a mechanical Euler angle system) when you have three gimbals in three dimensions - see the Wikipedia article "Gimbal lock". If you wish to avoid the problem of gimbal lock, you must first introduce a redundant (fourth) gimbal, and then use the additional mechanical degree of freedom to keep the system sufficiently far away from combinations of angles that would produce gimbal lock. The inherent stability of quaternions (or, better, the geometric algebra of Euclidean 3-space) may help to avoid computational instabilities of choosing Euler angles that do not correspond to the respective gimbal angles, but solve the mechanical problem first.

-
right quick update, lets say I want to only keep the pitch (y) component of the rotation , if I zero the other axis and re-normalize the quaternion I obtain a rotation only on the pitch axis (as needed) and can compute the other two axis tehe same way. Only problem with this approach is it doesn't work when the normalize parameter becomes very small. any thoughts on this approach and how I could avoid this singularity ? Cheers, Mihai. – user56921 Jan 11 '13 at 18:18
think I solved it! anyone with quat knowledge could you please have a look and check if there is a better way of implementing this ? Cheers, Mihai – user56921 Jan 11 '13 at 18:47