# Transform a vector to global frame and ignore rotation about one axis or Full tilt compensated magnetometer

Good day everyone. I would like to lock the rotation about one specified axis. For example, let`s imagine that we have a quaternion which desribes the orientation of our rigid body relative to the global frame - $q$ To null the rotation about z-axis in global coordinate frame i do the following:

1. Convert the conjugate quaternion $q^{-1}$ to euler angles.
2. Zero the yaw (heading) angle (it is the same as rotation about z-axis in global coordinate frame)
3. Convert the euler angles back to the quaternion.

After these steps i have an orientation which rotates only about $X$ and $Y$ axes in global coordinate frame, but not about $Z$ frame.

The question is - are there any more efficient alternative for this problem? May be someone has some examples for this problem in Matlab? Thanks.

Update: Today i tried an approach suggested by rschwieb. Imagine that i have a vector (magnetometer readings), measured in sensor frame and i want to represent this vector in world coordinate frame but ignore the rotation around Z-axis (parallel to the gravity vector). Also I have a quaternion $q$, which describes the sensor orientation relative to the global frame. To do so i use the following scheme.

1. Represent the vector, orthonormal to Z-axis, in sensor frame (for example, it can be x-axis): $x' = qxq^{*}$, where $x = [1;0;0]$
2. Project the transformed vector onto the plane: $p = z' - (dot(z', z)z)$ and then normalize it
3. Find an angle between the projected vector and orthonormal one, $\theta$
4. Build new quaternion: $q_{n} = [cos(\frac{\theta}{2}); sin(\frac{\theta}{2})z_x; sin(\frac{\theta}{2})z_y; sin(\frac{\theta}{2})z_z;]$
5. Multiply new quaternion with original one: $q_{nulled}^{z} = qq_n$
6. Transform vector from sensor coordinate frame to global, but ignore rotatione about z-axis: $z = q_{nulled}^{z}*m*q_{nulled}^{z*}$ , where $m$ - magnetometer readings. What i expect to see: the magnetometer readings, presented in global coordinate frame but without rotation about Z-axis. What i get: the magnetometer readings, which seems to be right, but they flip over when i change the orientation of the sensor.

Update2 This method gives the same results as an extraction of the roll and pitch angles from quaternion and then use this angles to transform the vector to the global coordinate frame. With both methods i keep getting the change of the sign of the vector when turning upside down the device around global Z-axis. Are there any legit ways to prevent it? I have a similar problem to this one: http://stackoverflow.com/questions/20821233/tilt-compensation-doesnt-work-with-pitch-bigger-than-90-degrees

Ok, i am stuck with this question - if someone has any thoughts, let me know please.

-
Thank you for your comment. I use left-handed coordinate system. Today i tried an approach suggested by you in other question. Please, check my edited question. I need to transorm the vector from local to global coordinate frame and ignore the rotation about Z-axis in global frame. Thanks. – S M May 7 '14 at 15:35
I didn't really have any question about the orientation convention you were using, but I guess it's good you mentioned it since I thought most people used the right-hand version. Anyhow, I was referring to the conventions about the order of the three rotations mentioned on the wiki, zxz, xyx, yxz and so on. – rschwieb May 9 '14 at 13:03
Thanks, i use ZYX convention. phi - rotation around $X$, theta - around $Y$, psi - around $Z$ axes. – S M May 9 '14 at 13:15
Thanks. Also, I'm trying to understand update2 above. What is "turning upside down the device around the global Z-axis"? I thought you would use the $z$ axis as "up," so it doesn't make any sense to turn around the z-axis and interchange up and down. What direction is "up" in the global coordinates? – rschwieb May 9 '14 at 14:46
Sorry for being unclear. "turning the device upside down" actually means that i rotate the device around X or Y axes, not Z. – S M May 9 '14 at 18:38