Normalising angled Earth magnetic field

Me and my team are participating in ESA Astro Pi challenge. Our program will ran on the ISS for 3 hours and we will our results back and analyze them.

We want to investigate the connection between the magnetic intensity measurements from Sense HAT magnetometer and predictions from the World Magnetic Model (WMM). We want to research the accuracy of the magnetometer on Sense HAT.

The program will get raw magnetometer data (X, Y and Z) in microteslas from Sense HAT and calculate values H and F as described in British geological survey's article (section 2.1). It will then save them to CSV file, along with timestamp and location calculated with ephem.

We will then compare values Z, H and F from ISS and WMM and create maps with our data and differences (like figures 6, 8 and 10). We will then research, how accurate are Sense HAT magnetometer data.

We want to compare our data with data from WMM to see how accurate is Sense HAT magnetometer, but we have a problem that orientation of magnetometer will always be different. Because of that, our data will always be (very) different from WMM so we won't be able to compare them correctly.

We talked with Astro Pi support team and they suggested to "normalise the angled measurements so it looks like they were taken by a device aligned North/South".

Unfortunately, we (and they) don't know how to do this, so they suggested to ask this question.

How can we do this? We have data for timestamp, ISS location (latitude, longitude, elevation), magnetic data (X, Y and Z) and also direction from the North.

We want to normalise our data so we will be able to correctly compare them with data from WMM.

I've got the answer on StackOverflow by Spektre:

I think you need to create local reference coordinate system similar to NEH (north,east,height/altitude/up) something like

Its commonly used in aviation as a reference frame (heading is derived from it) so your reference frame is computed from your geo location and its axises pointing to North, East and Up.

Now the problem is what does it mean aligned North/South and normalizing.. ?

If reference device measure just projection than you would need to do something like this:

dot(measured_vector,reference_unit_direction)

where the direction would be the North direction but as unit vector.

If the reference device measure a full 3D too then you need to transform both reference and tested measured data into the same coordinate system. That is done by using

So simple matrix * vector multiplication will do ... Only then compute the values H,F,Z which I do not know what they are and too lazy to go through papers ... would expect E,H or B vectors instead.

However if you do not have the geo location at moment of measure then you have just the North direction in respect to the ISS in form of Euler angles so you can not construct 3D reference frame at all (unless you got 2 known vectors instead of just one like UP). In such case you need to go with the option 1 projection (using dot product and north direction vector). So you will handle just scalar values instead of 3D vectors afterwards.

[Edit1]

From the link of yours:

The geomagnetic field vector, B, is described by the orthogonal components X (northerly intensity), Y (easterly intensity) and Z (vertical intensity, positive downwards);

This is not my field of expertise so I might be wrong here but this is how I understand it:

B(Bx,By,Bz) - magnetic field vector
a(ax,ay,az) - acceleration

Now F is a magnitude of B so its invariant on rotation:

F = |B| = sqrt( Bx*Bx + By*By + Bz*Bz )

you need to compute the X,Y,Z values of B in the NED reference frame (North,East,Down) so you need the basis vectors first:

Down = a/|a|  // gravity points down
North = B/|B| // north is close to B direction
East = cross(Down,North) // East is perpendicular to Down and North
North = cross(East,Down) // north is perpendicular to Down and East, this should convert North to the horizontal plane

You should render them to visually check if they point to correct directions if not negate them by reordering the cross operands (I might have the order wrong I am used to use Up vector instead). Now just convert B to NED :

X = dot(North,B)
Y = dot(East,B)
Z = dot(Down,B)

And now you can compute the H

H = sqrt( X*X +Y*Y )

The vector math needed for this you will find in the transform matrix link above.

beware this will work only if no accelerations are present (the sensor is not on a robotic arm during its operation, or ISS is not doing a burn...) Otherwise you need to obtain the NED frame differently (like from onboard systems)

If this not work correctly then you can compute NED from your ISS position but for that you would need to know the exact orientation and displacement of the sensor in respect to your simulation model that provide your location. I do not know what rotations ISS do so I would not touch that subject unless as a last resort.

I am afraid that I will not have time for coding for some time ... anyway coding without sample input data nor the coordinate system expalnations and all the input/output variables is insanity ... simple negation of axis will invalidate the whole thing and there is a lot of duplicities along the ways and to cover all of them you would end up with many many versions to try to...

Apps should be build up incrementally but I am afraid that without the access to simulation or real HW that is not possible. And there is a whole bunch of things that could go wrong ... making even simple programs a magnitude harder to code... I would first check the F as it does not require any "normalization" first to see if the results are off or not. If off it might suggest different units or god knows what ...