Question

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 services and therefore I'm not interested in getting the True north but rather the Magnetic North (using only the device's magnetometer).

Which class (or coding process.. ) could provide me with that value (solely relying on the magnetometer) ?

the CLLocationManager class and its properties rely on Location Services being enabled/available

where as the Core Motion framework with its CMMagnetometerData class provides us with the following property:

@property(readonly, nonatomic) CMMagneticField magneticField

A structure containing 3-axis magnetometer data

typedef struct {
   double x;
   double y;
   double z;
} CMMagneticField;

How do I get degrees out of that? or is there some other way (class/property/method) for getting degrees out of the magnetometer solely ?

Thank you in advance to anyone with some helpful information on that matter! :)

Was it helpful?

Solution

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;

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top