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.