在iOS中,来自Core Location和Core Motion框架的磁场值有什么区别?

我有两种使用iOS设备的磁力仪获取磁场(强度,x,y和z)的方法。

1)核心位置
使用CLLocationManagerDelegate方法的locationManager:didUpdateHeading:方法locationManager:didUpdateHeading: 这与Apple的Teslameter示例应用程序类似。

2)核心运动
使用CMMagneticFieldmagnetometerData.magneticField CMMotionManager

问题:
a)两者有什么区别? 我从两个不同的价值。 我期待他们会返回相同的值。
当我从rest位置开始应用程序(面朝上在桌子上)时,差异最为显着,然后将设备提升到空中。
b)如果有差异,我应该在什么时候使用核心位置标题中的磁场,什么时候应该使用Core Motion的磁场?

注意:我也不确定Core Location和Core Motion的“磁场”是指不同的磁场概念。
注:我计算强度为两个方法的(x ^ 2 + y ^ 2 + z ^ 2)的平方根。

为了解开这个问题,我花了很多时间仔细阅读苹果文档。

有三种获取磁力计数据的方法

1 / Core Motion框架
CMMotionManagers的CMMagnetometer

2 / Core Motion框架
CMDeviceMotion CMCalibratedMagneticField属性

3 / 核心位置框架
CLLocationManager的CLHeading

1 /从磁力计提供“原始”数据。
2 /和3 /返回“派生”的数据。 在这两种情况下的数字是相似的(虽然不完全一样)。

Core Motion的CMMagnetometer和CMCalibratedMagneticField之间的区别

1 /和2 /都来自Core Motion框架 – 不同之处如下:

CMDeviceMotion类参考

 @property(readonly, nonatomic) CMCalibratedMagneticField magneticField 

讨论
由该属性返回的CMCalibratedMagneticField为您提供设备附近的总磁场,而不会产生设备偏差。 与CMMagnetometer类的磁场属性不同,这些值反映了地球的磁场加上周围的场,减去设备偏差。

CMMagnetometer给我们原始数据,CMCalibratedMagneticField是调整数据。

Core Motion的CMC校核磁场与Core Location的CLHeading之间的区别

这个文档并没有立即清楚2 /和3 /之间的差别,但是它们确实产生了不同的数字,所以我们来做一些挖掘…。

核心位置框架
CLHeading

来自位置感知编程指南

获取标题相关事件

标题事件可用于包含磁力仪的设备上运行的应用程序。 磁力计测量从地球发出的附近磁场,并使用它们来确定设备的精确定位。 虽然磁力计可能会受到局部磁场的影响,例如audio扬声器,电机和其他许多types的电子设备中发现的磁场,但核心位置足够智能,可以过滤随设备移动的磁场。

以下是相关的CLHeading “原始”属性

 @property(readonly, nonatomic) CLHeadingComponentValue x @property(readonly, nonatomic) CLHeadingComponentValue y @property(readonly, nonatomic) CLHeadingComponentValue z 

[x | y | z]轴的地磁数据(用微写法测量)。 (只读)
该值表示设备跟踪的磁场线的[x | y | z]轴偏差。 ( 旧版本的文档添加 :)此属性报告的值标准化为-128至+128的范围。

我不清楚microotesla测量是如何被“标准化”(压缩?剪切?)到+/- 128的范围,仍然代表它声称测量的单位。 也许这就是为什么从文档中删除这个句子的原因。 iPad mini上的单位似乎符合这种范围,但iPhone4S给CMMagnetometer读数更高的范围,如200-500。

API显然期望您使用派生的属性:

 @property(readonly, nonatomic) CLLocationDirection magneticHeading @property(readonly, nonatomic) CLLocationDirection trueHeading 

它们以度数(0 =北,180 =南等)给出稳定的N / SE / W指南针读数。 对于真正的航向,需要其他的核心位置服务(地理位置)来获得真正的北方磁场的偏差。

这是来自CLHeading头文件的一个片段

 /* * CLHeading * * Discussion: * Represents a vector pointing to magnetic North constructed from * axis component values x, y, and z. An accuracy of the heading * calculation is also provided along with timestamp information. * * x|y|z * Discussion: * Returns a raw value for the geomagnetism measured in the [x|y|z]-axis. 

Core Motion框架
CMDeviceMotion CMCalibratedMagneticField

 /* * magneticField * * Discussion: * Returns the magnetic field vector with respect to the device for devices with a magnetometer. * Note that this is the total magnetic field in the device's vicinity without device * bias (Earth's magnetic field plus surrounding fields, without device bias), * unlike CMMagnetometerData magneticField. */ @property(readonly, nonatomic) CMCalibratedMagneticField magneticField NS_AVAILABLE(NA,5_0); 

CMMagnetometer

  * magneticField * * Discussion: * Returns the magnetic field measured by the magnetometer. Note * that this is the total magnetic field observed by the device which * is equal to the Earth's geomagnetic field plus bias introduced * from the device itself and its surroundings. */ @property(readonly, nonatomic) CMMagneticField magneticField; 

CMMagneticField
这是保存向量的结构。
CMDeviceMotion的校准磁场和CMMagnetometer的未校准版本是一样的:

 /* CMMagneticField - used in * CMDeviceMotion.magneticField.field * CMMagnetometerData.magneticField * * Discussion: * A structure containing 3-axis magnetometer data. * * Fields: * x: * X-axis magnetic field in microteslas. * y: * Y-axis magnetic field in microteslas. * z: * Z-axis magnetic field in microteslas. 

2 /和3 /的区别在这里暗示:

核心位置CLHeading

表示由轴分量值x,y和z构成的指向磁北的向量

核心位置足够聪明,可以过滤出随设备移动的字段

核心运动CMCalibratedMagneticField

[代表]地球磁场加上周围的领域 ,没有设备偏见

所以 – 根据文档 – 我们有:

1 / CMMagnetometer
原始读数从磁力计

2 / CMDeviceMotion(CMCalibratedMagneticField *)磁场
针对器件偏差校正的磁力计读数(机载磁场)

3 / CLHeading [x | y | z]
磁力计读数经过设备偏置校正,并过滤以消除局部外部磁场(如设备移动所检测到的 – 如果磁场随设备一起移动,忽略它,否则测量)

testing理论

在这里输入图像说明

我在gitHub上放了一个Magnet-O-Meter演示程序,它显示了这些差异。 当应用程序运行时,在设备周围划一个磁铁,并观察各种API如何反应,这是相当明显的:

CMMagnetometer对任何事情都没有什么反应,除非你把稀土磁铁拉近 。 机载磁场似乎远比当地外部磁场或地球磁场重要。 在我的iPhone 4S上,它始终指向设备的左下angular; 在iPad mini上它通常指向右上angular。

CLHeading。[x | y | z]对本地外部域来说是最脆弱的(敏感的),无论是相对于设备的移动还是静态的。

(CMDevice) CMCalibratedMagneticField是面对不同的外部字段时最稳定的,但是另外跟踪它的核心位置对话CLHeading。[x | y | z]非常接近。

CLHeading.magneticHeading – 苹果公司推荐的磁罗盘阅读 – 比任何一个都要稳定得多。 它使用来自其他传感器的数据来稳定磁力计数据。 但是你没有得到x,y,z的原始分解

  influenced by onboard fields local external fields earth's field yellow XXX green _ XX blue _ _ X red _ _ X 

CMMagnetometer
绿色CLHeading。[x | y | z]
蓝色CMCalibratedMagneticField
红色的CLHeading.magneticHeading

这似乎与文档相矛盾,这表明CLHeading。[x | y | z]应该比CMCalibratedMagneticField更less受当地外部领域的影响。

你应该采取什么方法? 基于我有限的testing,我会build议…
如果你想要一个指南针读数
CLHeading的magneticHeading trueHeadingtrueHeading将为您提供最准确和最稳定的指南针阅读。
如果你需要避免核心位置
CMDeviceMotion的CMCalibratedMagneticField似乎是下一个最希望的,虽然相比magneticHeading更不稳定和准确。
如果你对当地的磁场感兴趣
CLHeading的“原始”xy和z属性似乎对局部磁场更敏感。
如果你想要所有的数据,包括板载磁场
来自CMMagnetometer的原始磁力计数据。 除非您准备进行大量的过滤,否则实际上没有多less意义,因为它受到设备本身产生的磁场的巨大影响。

这个答案是基于我对下面的文档链接的解释

http://developer.apple.com/library/ios/#documentation/CoreLocation/Reference/CLHeading_Class/Reference/Reference.html#//apple_ref/doc/c_ref/CLHeading

http://developer.apple.com/library/ios/#documentation/CoreMotion/Reference/CMMagnetometerData_Class/Reference/Reference.html#//apple_ref/doc/c_ref/CMMagnetometerData

a)CLHeading是“与设备跟踪的磁场线偏离 ”,而magnetometerData.magneticField是设备观察到的总磁场 ,等于地球的地磁场加上设备本身及其周围的偏差“ 。

所以CLHeading给你过滤的值,其中的参考帧是地球现有的磁场。 而磁力计数据为您提供了未经过滤的值,参考帧是设备。

b)如果你正在做任何你想知道哪里是磁性或真正北方的位置,我build议使用CLHeading。 如果您想要创build一个应用程序来响应设备附近的磁场,或者您想要执行一些特定的传感器融合,可以尝试创build一个AHRS,然后使用CMMagneticField。

使用CLHeading。[x | y | z]值来计算局部磁场强度的一个重要事情是,CLLocationManagerDelegate方法

  • (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)pipe理器

应该设置为返回YES。 我发现,如果closures校准警告,那么磁力计的读数就不会被校准,结果当设备的方向改变时,计算的场强是非常不稳定的。

我认为磁力计数据。磁性字段它告诉你的加速度,而不是位置(因此,为什么你会得到大的价值从静止移动),而位置pipe理器提供的数据方向设备指向英寸。

Interesting Posts