Simple rotation question (hopefully)

Started by
22 comments, last by RobM 10 years, 4 months ago
I mean the vector the device is giving for orientation. Also, with regards to the accel vector, if you hold the device upright what reading do you get? I would assume (0,0,1). The acceleration vector should be relative to the device's coordinate system. If the acceleration vector was in world coordinates then it would read (0,1,0) always, because gravity is always the same in world space! (this all assumes no one is shaking or dropping the device, and gravity is the only force affecting the accelerometer)
Advertisement
Ah ok... Yes, upright is always 0,1,0 for the accelerometer when you hold it flat and indeed it's 0,0,1 if you hold it on its edge. So it's in the normal world's coordinate space.

Thanks so much for the pseudo code and your help so far, unfortunately I haven't got time to try this practically until Sunday but ill do some drawing and calcs and check it out.
I've spent a bit of time on this today and I still can't get my head around it. I've been trying to visualise the magnetic vector from the sensor and I've finally got my head around what it looks like when the sensor rotates.

Problem is, because there's only a vector, I can't see how you can tell which way the sensor is 'pointing' in order to find the yaw.

Essentially, I've been envisaging it this way:

When the sensor is flat and z is pointing to magnetic north, the imaginary Earth's magnetic vector is pointing toward positive Z and down into the ground (or into the sensor let's say)...

When the sensor rotates and you take the magnetic vector, because it's just a vector you can't really tell its orientation because you need the rotation about that vector. I can kind of see why crossing vectors might give you this but if you cross vectors initially, how do you work out how those crossed vectors are oriented if they are based on the original vector?

I'm really confused about what type(s) of vector(s) you have right now and what values it/they can take, but if you already have the pitch and roll, then you could use those to rotate the magnetic vector into a reference position. Then you can use this new vector to find the yaw, by simply extracting the x and z coordinates (assuming that your reference position is the y=0 "horizontal" position we were talking about before).

Keep in mind that D3DXMAtrixRotationYawPitchRoll function applies the rotations in this order: roll first, then pitch, then yaw (but you are not using the yaw at this point). If your magnetometer's pitch is independent of the roll, then this is ok. If not, you'll have to make your own transformation matrix for the rotation, in which you'd apply pitch first, then roll.

I'm really confused about what type(s) of vector(s) you have right now and what values it/they can take, but if you already have the pitch and roll, then you could use those to rotate the magnetic vector into a reference position. Then you can use this new vector to find the yaw, by simply extracting the x and z coordinates (assuming that your reference position is the y=0 "horizontal" position we were talking about before). Keep in mind that D3DXMAtrixRotationYawPitchRoll function applies the rotations in this order: roll first, then pitch, then yaw (but you are not using the yaw at this point). If your magnetometer's pitch is independent of the roll, then this is ok. If not, you'll have to make your own transformation matrix for the rotation, in which you'd apply pitch first, then roll.


Thanks, that YawPitchRoll info is pretty important.

I'm slowly but surely starting to work this out. The magnetic vector (which is a static vector in world space but a relative vector in local sensor space) should effectively be a set angle away from the gravity vector (provided by the accelerometer which, in world space, always points down) no matter what orientation you have the sensor in, these two should be the same distance (angle, to be more precise) apart.

In order to find the yaw (in a way that makes sense in my head at least), I think I just need to rotate the gravity vector so it is pointing directly up (or down) and then rotate the magnetic vector by the same rotation - that should the give me x and z for the yaw. If the gravity vector is closer to pointing up than down (relative to the sensor obviously) then the sensor is upside down and vice versa.

Samith, is this roughly where you were headed with the pseudo code? I find it difficult to visualise what the code is doing without either drawing a diagram or describing a use case.

tonemgub's answer is much simpler than mine, and more robust. I had forgotten that your device has a gyro, which makes the problem easier to solve.

My solution is passable in a situation where a gyro (and thus pitch and roll information) is not readily available. My solution works by using the sensor's measurements of gravity and the magnetic field to construct a sensor space coordinate system that represents world-up, world-north, and world-right. Then you transform the sensor local positive z into that coordinate space you constructed, and use the transformed vector's x and z to find yaw. This is very difficult to describe with just text, but it's truly not very complicated (you just have to have a good mental picture beforehand smile.png). I could try and draw up some diagrams for you, if you'd like, but I think using tonemgub's method is going to serve you better in the long run.

Thanks for the help on this guys, it's much appreciated.

I'm pretty sure from both of those replies I've finally grasped it. Annoyingly for me, what tonemgub is saying was pretty much exactly what I first tried but I don't think I had the correlation between the magnetic vector and the accelerometer values quite right in my head (or rather the correct alignment with regard to sign) and as it didn't work, I moved on to try something else.

So effectively I can rotate my relative magnetic vector by the inverse of the pitch and roll matrix (which is the same as bringing the gravity vector back in alignment) and we should be there. I'll try it tonight and report back.

Thanks again guys

Edit: I've also just realised that I should be able to smooth my accelerometer values with the magnetic vector using a complimentary filter as I do with the gyro and accelerometer. By smoothing the accelerometer values I mean I can probably estimated where gravity should be and get rid any sudden movement readings

The magnetic vector is effectively the sensor's own world axis.

No, it's just a vector pointing north that you want to use to find a plane and then compute projections and angles.

I need to be able to get the local yaw of the sensor regardless of its orientation. To do that I felt I needed to go into the sensor's local coordinate space but now I'm not so sure.

If I understand correctly, you want a cartesian coordinate system tied to a certain point of the surface, in which axis z points "up" along the direction of gravity at that point (or more simply along the surface normal, treating Earth as a sphere).

Choice of x and y axes in the tangent plane at that point has one degree of freedom, which can be used either to place axis y in the plane spanned by the z axis and the north vector (so that it points towards the magnetic north) or to place axis y along a geographical meridian (so that the projection of the magnetometer reading on the xy plane work like a compass).

All angles you mention are measured between the x,y or z axes and the north vector or its projections on the xy, yz or xz planes, all of which are easy to find.

Omae Wa Mou Shindeiru


Annoyingly for me, what tonemgub is saying was pretty much exactly what I first tried but I don't think I had the correlation between the magnetic vector and the accelerometer values quite right in my head (or rather the correct alignment with regard to sign) and as it didn't work, I moved on to try something else.

Your problem is that you're looking at it as having to translate something from one "coordinate space" to another but there's actually no coordinate space that is clearly defined in your problem. The magnetometer's "local" coordinate system does not have a center of origin - you just have a vector that has a varying orientation, but you have no position information about where it points from, or where it points to - you don't have the position of the magnetometer, and you don't have the position of the "magnetic North" point.

Your info that the magnetometer's magnetic vector always points to "magnetic north", and that this vector is always at "an angle of roughly 60 degrees (from horizontal)" does not define another coordinate system that the magnetometer's yaw, pitch and roll can be interpreted as being relative to - they are just your way of interpreting the magnetometer's info.

If you want to talk about the yaw, pitch and roll of the magnetometer relative to a coordinate sapce, you have to define what it's relation is to the coordinate space, specifically: where is the origin of the coordinate system, and where do the X, Y and Z axes point to, and you have to clearly position the magnetometer into this space.

Otherwise, you only have the roll and pitch of the magnetometer (which I assume are relative to the surface of the Earth as long as the magnetometer doesn't go out into space, but that doesn't give you an idea of a coordinate space - your "Earth" could be any shape, any size, anywhere), and a 3D vector that points from nowhere to nowhere...

Annoyingly for me, what tonemgub is saying was pretty much exactly what I first tried but I don't think I had the correlation between the magnetic vector and the accelerometer values quite right in my head (or rather the correct alignment with regard to sign) and as it didn't work, I moved on to try something else.

Your problem is that you're looking at it as having to translate something from one "coordinate space" to another but there's actually no coordinate space that is clearly defined in your problem. The magnetometer's "local" coordinate system does not have a center of origin - you just have a vector that has a varying orientation, but you have no position information about where it points from, or where it points to - you don't have the position of the magnetometer, and you don't have the position of the "magnetic North" point. Your info that the magnetometer's magnetic vector always points to "magnetic north", and that this vector is always at "an angle of roughly 60 degrees (from horizontal)" does not define another coordinate system that the magnetometer's yaw, pitch and roll can be interpreted as being relative to - they are just your way of interpreting the magnetometer's info. If you want to talk about the yaw, pitch and roll of the magnetometer relative to a coordinate sapce, you have to define what it's relation is to the coordinate space, specifically: where is the origin of the coordinate system, and where do the X, Y and Z axes point to, and you have to clearly position the magnetometer into this space. Otherwise, you only have the roll and pitch of the magnetometer (which I assume are relative to the surface of the Earth as long as the magnetometer doesn't go out into space, but that doesn't give you an idea of a coordinate space - your "Earth" could be any shape, any size, anywhere), and a 3D vector that points from nowhere to nowhere...

I may have misinterpreted things or perhaps misrepresented my ideas but the way I see it, you don't need position. Regardless of which direction the earth's 'static' magnetic vector is pointing, that coupled with knowing exactly where 'up' is is enough to construct some form of reference point within the sensor. If that's not a coordinate space in some form then I probably need to read up on my terminology.

To aid my understanding, my 3d app shows a line for 'up' (relative to the sensor) and a line for the magnetic field vector (also relative to the sensor), both unit vectors starting at 0,0,0. The up obviously points directly up and the magnetic vector points up but slightly to -z as expected when the sensor is lined up with north (using a 'real' compass).

When I rotate the sensor around, these two stay the same angle apart but obviously move around relative to the sensor. The fact that at all times I know where up is means I can get the inverse of the rotation to get from 'real' up to 'relative' up and take that away from 'relative' mag. This effectively brings the relative up vector back to real up and puts the relative magnetic vector next to it. The x,z position of that mag vector relative to 0,1,0 should be my tilt-compensated yaw.

This topic is closed to new replies.

Advertisement