Search code examples
androidjava-native-interfaceandroid-sensorsmagnetometer

Uncalibrated Magnetometer Issues


I have been working with Android's calibrated magnetometer for some time, feeding it into our algorithm for the rotation vector values to calculate the correct yaw/orientation with North. In spite of dealing with not completely projecting the yaw onto a plane that is parallel with the ground to get true yaw independent of pitch, we have been noticing that even after we calibrate the magnetometer - using the calibrated magnetometer values and moving the phone in figure eights and other movements/orientations - the calibrated values seem to eventually try to recalibrate.

With this in mind, we decided to start looking specifically at the uncalibrated values given by Android within our JNI code. Within the struct "ASensorEvent", there is "uncalibrated_magnetic", which is the struct "AUncalibratedEvent" - all of this is defined in "android/sensor.h". I assumed that this would give me uncalibrated values; however I was mistaken - at least on the devices I check it on - and was given the supposed calibrated values. Being that in the "sensor.h", the only enums for sensors that are explicitly defined are...

ASENSOR_TYPE_ACCELEROMETER      = 1,
ASENSOR_TYPE_MAGNETIC_FIELD     = 2,
ASENSOR_TYPE_GYROSCOPE          = 4,
ASENSOR_TYPE_LIGHT              = 5,
ASENSOR_TYPE_PROXIMITY          = 8

...I decided to directly type in 14 assuming this would give me the uncalibrated magnetometer values since this is the values that is associated with the magnetometer outside of JNI http://developer.android.com/reference/android/hardware/Sensor.html#TYPE_MAGNETIC_FIELD This gave the uncalibrated magnetometer values that corresponded with those outside of JNI.

So, at this point, we decided to plot the values given and we noticed something strange. x-axis is the y-values given and the y-axis is the z-values given

Here, you can see the x-axis are the y-values given and the y-axis the z-values given by the uncalibrated magnetometer - however, the axes are irrelevant since it can be seen across all axes. At the bottom left, you'll notice a "j" figure rotated roughly 150 degrees clockwise. These "j" figure values were at the beginning of data collection and lasted for around 20 seconds.

We haven't always seen this in our data collection, but around 50% of the time we have seen this. I really have no idea what this is. I mean I assume it isn't some weird hard iron offset since I imagine such an offset to be close to offset that is visible with a majority of the data and I'd assume it wasn't soft-iron skewed values because the environment was consistently the same at least after 1 second until the end of data collection (lasted for about 200s) and sometimes was the same throughout the whole trace.

I guess we are starting to speculate that we are not truly getting uncalibrated/raw values.

Thanks in advance.


Solution

  • As written on http://developer.android.com/guide/topics/sensors/sensors_position.html#sensors-pos-magunc

    "Factory calibration and temperature compensation are still applied to the magnetic field." Hope it helps!