Which iOS class/code returns the magnetic North?
Asked Answered
S

2

8

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! :)

Sedimentation answered 8/7, 2012 at 14:40 Comment(0)
C
12

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;
Carrizales answered 24/7, 2012 at 20:31 Comment(4)
what if I want to get the Magnetic North regardless of how I'm holding the device? e.g. the digital compass on the iPhone 4S returns the Magnetic North (location services disabled) regardless of how I'm holding the device. How can I achieve that?Sedimentation
the formula you suggested is not valid Objective-CSedimentation
To get magnetic north regardless of how you hold the device, I guess you should use the filtered magnetic values of CMDeviceMotion, instead of the unfiltered values of CMMagnetometerData.Carrizales
The wording kind of makes it seem like you can calculate declination with just the x and y variables. This is not possible. Longitude, Latitude, Altitude, and time are required to calculate declination. As shown in this Android source code that calculates it. android.googlesource.com/platform/frameworks/base/+/refs/heads/…Pow
B
-2

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.

Blair answered 8/3, 2013 at 21:37 Comment(1)
Have you read the question? Please check carefully what the author was asking for.Leslie

© 2022 - 2024 — McMap. All rights reserved.