I’ve just posted the latest code to GitHub, and I think it’s nigh on perfect (IMHO) – there’s now nothing on my mental ‘niggle’ list that could make it better.
However (and it’s a very big however), it requires nigh on perfect accelerometer calibration. To give you an idea, if the accelerometer reads gravity as 1.001g rather 1.0g (0.1% accuracy), then you’ve get drift at roughly 1cm/s2 and that builds up to significant drift beyond a few seconds of flight. Yet the sensors alone are only rated at ±2% accuracy, or 20cm/s2. The 0.1% accuracy error I mention represents a twenty fold improvement over the base 2% level of calibration and is my current best effort but it still limits the flights to tens of seconds rather than minutes in length.
So here in detail is what I do:
- find two locations with a broad and stable temperature differential – in my case a beer fridge, and the warmest room in the house – in my case, my home office as it has way too many computers in it!
- Separate the Raspberry Pi from the quad frame and stick it to the inside of a 5 sided perspex cube aligned closely with one edge of the cube.
- Within both environments, ensure the platform for the cube is flat and horizontal – I have a 10mm thick perspex square with wing-nut bolts at each core and a 0.5° accuracy spirit level to get the best horizontal possible: I sit the beer fridge on this, or just the cube on this depending on the required temperature environment.
- Within each of the two temperature environments, I then rotate the cube on each of the six sides, reading sensors (sudo python ./qc.py -c) each time until I have a sample for each that is within half of a degree (celsius / centigrade) of each other according to the sensor output – that’s about as good as I’ve achieved so far because the sensor warms up the more samples you take!
- From the sensor readings of 1g over the six sides of the cube at a given temperature, you can calculate the offset and gains of those axes such that each reads ±1g at that temperature.
- With those offsets and gains at two diverse temperature points, you can then calculate a linear mapping between and beyond those temperature points to allow calculation of offsets and gains at any operating temperature. The sensor output is reportedly linear across temperature at ±2% also and that should be good enough – 2% error in gain / offset at a given temperature is much better than 2% error in absolute readings.
Here’s the data I’ve obtained and sorted. The leftmost column is raw temperature readings. The rightmost 4 columns are gravity measured over 3 axes, in both directions at two temperature ranges. Column 2 is temperature in celsius / centrigrade – I don’t use this in the calibration, but it makes it easier to spot a small range of temperature values. The accelerometer scale is set to ±2g so the values of ±16384 are whats expected, and are the targets of the calibration calculation.
-3393, 26.550588, 16537.84, -294.84, -842.44
-3383, 26.58, -16404.88, -14.1, -1062.72
-3390, 26.559412, 179.44, 16369.72, -953.2
-3391, 26.556471, -59.44, -16662.18, -974.54
-3383, 26.58, 45.62, -176.4, 15436.18
-3386, 26.571176, 75.52, -94.92, -17342.8
-6517, 17.362353, 16505.3, -275.08, -531.38
-6543, 17.285882, -16426.64, 1.22, -846.94
-6484, 17.459412, 185.44, 16368.36, -695.24
-6462, 17.524118, -55.6, -16649.48, -707.32
-6552, 17.259412, -38.96, -177.82, 15697
-6552, 17.259412, 96.96, -75.92, -17063.76