# 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

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