i was wondering how i could use only a HMC5883L to find the azimuth and altitude of a heliostat. I mean since the location of a heliostat is static (latitude and longitude wise), the magnetic vector of that location is know - it should therefore be theoretically possible to use the 3 axis reading from the HMC5883L to determine the azimuth and elevation of the heliostat it is mounted on?

Is my above assumption correct? if yes, could someone please point me to a library or the necessary maths to do this. Have been searching the net and have found all kinds of vector and Quaternions equations which are all a bit beyond me as of now

I’ve been thinking about a similar issue. In principle, you can do what you want. The magnetometer gives you 3 measurements but their absolute scale is not known. If you have accurate knowledge of the magnetic vector (magnitude and angle of inclination) at your location, that allows you to scale the three measurements, leaving two independent values and an absolute indication of North. Obviously, you can’t determine the rotation about the magnetic vector, but I believe that the remaining information is in principle enough to determine the other two angles.

I have not had time to work out the math, although I don’t think it is very hard, nor have I done any on line research into the problem. However, if you have found a couple of links that seem promising, post them and I’ll take a look.

In any case, a great introduction into the math of creating a 3D compass (which uses a magnetometer and compass) is Freescale’s AN4248. Most of it is applicable to the problem. Google “freescale an4248” and it is the top hit.

Edit: for the most accurate magnetometer and resulting angular measurements, you will definitely need to calibrate the magnetometer. It is relatively easy to do. My favorite procedure is described here: Sailboat Instruments: Improved magnetometer calibration (Part 1)

My first thought is that it will work, but the height might be only accurate to 1km, or maybe 10km. The change of the 3D magnetic vector does not change that much, and the sensor is not that accurate. It is just my feeling telling me this, so I might be wrong.

ADDED: I might have misunderstood your question. You do not want to know the absolute height ? But only the orientation of the heliostat ? The azimut and tilting ? That is not only possible, it will work very well I think. You don't have information about the rotation around the magnetic vector as jremington wrote. But the heliostat only rotates around 2 axis, the 'unknown' axis is not used, as long as the top of the heliostat never tilts sideways. So I think that all the information is available to calculate the orientation of the heliostat.
A magnetometer is sensitive for magnetic disturbance by wires and metal, and a accelerometer is not.

Following the derivation in the Freescale application note AN4248 very closely, it is possible to derive a system of equations for the yaw (psi) angle and the pitch (theta) angle, given the local magnetic field strength B and magnetic inclination angle delta. Here, Bx, By and Bz are the magnetometer readings in the usual orientation (north is X and Z is down). Unfortunately the system is highly nonlinear and after pondering it for a bit, I don’t see a way to solve it for theta and psi. Any takers?

It turns out that if you do the rotations in a different order (unrotate by psi then unrotate by theta, see equation 9 of the Freescale application note) the resulting equations are easy to solve. I’ll post the full solution and code a bit later, after I have a chance to make sure I didn’t make any algebraic mistakes.

Caltoa:
My first thought is that it will work, but the height might be only accurate to 1km, or maybe 10km. The change of the 3D magnetic vector does not change that much, and the sensor is not that accurate. It is just my feeling telling me this, so I might be wrong.

ADDED: I might have misunderstood your question. You do not want to know the absolute height ? But only the orientation of the heliostat ? The azimut and tilting ? That is not only possible, it will work very well I think. You don't have information about the rotation around the magnetic vector as jremington wrote. But the heliostat only rotates around 2 axis, the 'unknown' axis is not used, as long as the top of the heliostat never tilts sideways.

Thanks - and yes am looking only for Azm and Alt, rotation around the magnetic vector (tilt) is not needed.

jremington:
It turns out that if you do the rotations in a different order (unrotate by psi then unrotate by theta, see equation 9 of the Freescale application note) the resulting equations are easy to solve. I'll post the full solution and code a bit later, after I have a chance to make sure I didn't make any algebraic mistakes.

Edit: derivation attached as PDF file

that will be absolutely brilliant, thanks in advance!!

In the meanwhile am working away to try and understand this sensor better, in particular to calibrate and get the readings in-line with what should be for my geographic location (limited success so far), but will keep at it!!

I posted the full solution earlier in reply #5.
At the moment I don't intend to write any Arduino code to test this, as I am using a different processor for my project.

It seems to me, that the assumption is being made there that the device is being held flat, that is, parallel to the ground. The magnetic field is a vector pointing diagonally into or out of the ground. For any given reading on the device, you could rotate the device about an axis aligned with the field and get the same reading.

As AN4248 makes clear, the reference frame is X north, Y east and Z down. So the reference XY frame is indeed parallel to the Earth’s surface. In that reference frame, the Earth’s magnetic field is a vector with an inclination angle of delta with respect to the X axis, and in the XZ plane. The calculation of pitch and yaw from the magnetometer readings make no assumption about the orientation of the magnetometer, but obviously these cannot be unique.

This is mostly an intellectual exercise. Since sensors that combine both a magnetometer and an accelerometer are becoming very cheap, it seems silly not to use both (as long as the sensor is not subject to acceleration other than gravity).

As an aside, there are much simpler ways of implementing a tilt-compensated compass that that described in AN4248. For example using a bit of vector algebra (taken from an example placed in the public domain by the Pololu engineers):

// Returns a heading (in degrees) given an acceleration vector a due to gravity,
// a magnetic vector m, and a facing vector p. Semantic mods to Pololu code example by J. Remington
int get_heading(const vector *a, const vector *m, const vector *p)
{
vector W;
vector N;
// cross magnetic vector (magnetic north + inclination) with "down" (acceleration vector) to produce "west"
vector_cross(m, a, &W);
vector_normalize(&W);
// cross "down" with "west" to produce "north" (parallel to the ground)
vector_cross(a, &W, &N);
vector_normalize(&N);
// compute heading
int heading = round(atan2(vector_dot(&W, p), vector_dot(&N, p)) * 180 / M_PI);
if (heading < 0)
heading += 360;
return heading;
}

jremington:
This is mostly an intellectual exercise. Since sensors that combine both a magnetometer and an accelerometer are becoming very cheap, it seems silly not to use both (as long as the sensor is not subject to acceleration other than gravity).

You are probably right that it may not be worth the effort, however, since am still waiting for the accelerometer to arrive will give this a shot anyway.