I want to get the device\'s deviation from the magnetic North in degrees, and use that value in some code I\'m writing.
I don\'t want to use the device\'s location
You need to fuse sensors to mimic the apple applications. They use the gyro accelerometer and magnetometer, and advanced mathmatics you may or may not have learned to produce such clean results. Good luck. You probably won't be able mimic them.
The iOS documentation states that the CMMagneticField data is raw, meaning that it includes bias introduced from the device itself and its surroundings. CMDeviceMotion provides the same magnetic field values filtered.
To determine magnetic north you should use the filtered values and the device should lay level with Earth's surface.
Knowing the x and y values of the magnetic field the angle (declination from magnetic north in degrees) can be calculated with the following formula:
if (y>0): heading = 90.0 - [arcTan(x/y)]*180/π
if (y<0): heading = 270.0 - [arcTAN(x/y)]*180/π
if (y=0, x<0): heading = 180.0
if (y=0, x>0): heading = 0.0
In Obj-C, assuming you have a CMMagnetometerData
object called magnetometerData
, that would look something like:
double heading = 0.0;
double x = magnetometerData.magneticField.x;
double y = magnetometerData.magneticField.y;
double z = magnetometerData.magneticField.z;
if (y > 0) heading = 90.0 - atan(x/y)*180.0/M_PI;
if (y < 0) heading = 270.0 - atan(x/y)*180.0/M_PI;
if (y == 0 && x < 0) heading = 180.0;
if (y == 0 && x > 0) heading = 0.0;