Internet’s back for now! (Thanks janie!) So I can run my mouth about my hobbies on the internet some more.
Finally got a chance to mess around with this in MATLAB. To recap, I’ve got a magnetometer that I need to calibrate. In a perfect world with a perfectly calibrated magnetometer, you should be able to move it all around in random orientations and get a set of points that, when graphed in three axes, form a sphere centered on the origin. Normally, however, what you get is more of an ellipsoid somewhere out in no man’s land.
Like that. (I got this dataset by the very scientific method of shaking my breadboard around while taking readings.) You can see it’s nowhere near the center. It’s also nowhere near spherical. This picture shows it a little better.
So I need to take this thing and move it onto the center, rotate it to align its axes with the coordinate axes, scale it onto a sphere, and derotate it. (The reason to rotate and then derotate is to get a set of scaling factors you can apply after calibration without going through all this mess to do it.)
Calculating the offsets I need to get this centered is pretty easy.
x_off = (xmax - xmin)/2 - xmax
Same deal for y and z axes.
I then found the major axis of the ellipsoid by calculating the magnitude of the vector to each point and finding the maximum of these. Rotating it to align with the x-axis is a little trickier. There are lots of ways to do this, but many of them are fairly computationally heavy. I wound up following the method outlined here, which is fairly simple.
Once I had the ellipsoid’s major axis lined up on the x-axis, I then found the largest axis in the y-z plane by finding the largest radius in those two dimensions. I then rotated again to line this up with the y-axis.
From here I calculated scaling factors in each axis to map the ellipsoid onto a sphere. I didn’t derotate in MATLAB, but it would done by multiplying by the inverse of the rotation matrices I already applied. Here’s what I got.
There’s almost certainly a better way to do this, and I suspect I’ll find things I missed here, but for now this is a good first step. Next to translate into some code an Arduino can handle.
MATLAB code under the cut. (Again, there’s likely a much better way to do this - rotation matrices aren’t an area I’ve dealt with much. MATLAB is also something I’m not anything like an expert in.)
Lees verder →