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

Miu*_*Miu 61 core-location magnetometer ios core-motion

我有两种方法可以使用iOS设备的磁力计获得磁场(强度,x,y和z).

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

2)核心运动
用于CMMagneticFieldCMMotionManagermagnetometerData.magneticField.

问题:
a)两者有什么区别?我从两者中得到了不同的价值观.我原以为他们会返回相同的值.
当我从静止位置(面朝上放在桌子上)启动应用程序,然后将设备向上提升到空中时,差异最为显着.
b)如果存在差异,何时应使用Core Location标题中的磁场,何时应使用Core Motion的磁场?

注意:我也不确定Core Location和Core Motion的"磁场"是否涉及不同的磁场概念.
注意:我将强度计算为两种方法的(x ^ 2 + y ^ 2 + z ^ 2)的平方根.

fou*_*dry 179

为了解开这个问题,我花了太多时间来挖掘Apple文档.

获得磁力计数据有三种方法

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
Run Code Online (Sandbox Code Playgroud)

讨论
此属性返回的CMCalibratedMagneticField可为您提供设备附近的总磁场,而无需设备偏差.与CMMagnetometer类的magneticField属性不同,这些值反映了地球的磁场加上周围的场,减去了器件偏置.

CMMagnetometer为我们提供原始数据,CMCalibratedMagneticField是调整后的数据.

Core Motion的CMCalibratedMagneticField与Core Location的CLHeading之间的区别

文档并没有立即明确2 /和3 /之间的区别,但是它们确实会生成不同的数字,所以让我们进行一些挖掘....

核心位置框架
CLHeading

来自位置感知编程指南

获得与标题相关的事件

在包含磁力计的设备上运行的应用程序可以使用标题事件.磁力计测量从地球发出的附近磁场,并使用它们来确定设备的精确方向.虽然磁力计可能会受到局部磁场的影响,例如那些来自音频扬声器,电机和许多其他类型电子设备中的固定磁铁的磁场,但核心位置足够智能,可以滤除随设备移动的磁场.

以下是相关的CLHeading"原始"属性

@property(readonly, nonatomic) CLHeadingComponentValue x
@property(readonly, nonatomic) CLHeadingComponentValue y
@property(readonly, nonatomic) CLHeadingComponentValue z
Run Code Online (Sandbox Code Playgroud)

[x | y | z]轴的地磁数据(以微格式测量).(只读)
该值表示与设备跟踪的磁场线的[x | y | z]轴偏差.(旧版本的文档添加 :)此属性报告的值规范化为-128到+128的范围.

我不清楚微特斯拉测量如何被"标准化"(压缩?剪切?)到+/- 128的范围,并且仍然代表它声称要测量的单位.也许这就是为什么从文档中删除了句子的原因.iPad mini上的单元似乎符合这种范围,但iPhone4S 可以在更高的范围内提供CMMagnetometer读数,例如200-500.

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

@property(readonly, nonatomic) CLLocationDirection magneticHeading
@property(readonly, nonatomic) CLLocationDirection trueHeading
Run Code Online (Sandbox Code Playgroud)

它以度为单位给出稳定的N/SE/W罗盘读数(0 =北,180 =南等).对于真实航向,需要其他核心位置服务(地理定位)以获得磁场与真北的偏差.

这是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.
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

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;  
Run Code Online (Sandbox Code Playgroud)

CMMagneticField
这是保存向量的结构.
它是同一个CMDeviceMotion"校准磁场和S 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.
Run Code Online (Sandbox Code Playgroud)

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

核心位置CLHeading

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

核心位置足够智能,可以过滤掉随设备移动的字段

Core Motion CMCalibratedMagneticField

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

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

1/CMMagnetometer
来自磁力计的原始读数

2/CMDeviceMotion(CMCalibratedMagneticField*)磁场磁
强计读数校正了器件偏置(板载磁场)

3/CLHeading [x | y | z]
针对设备偏差校正磁强计读数并进行滤波以消除局部外部磁场(通过设备移动检测到 - 如果磁场随设备移动,忽略它;否则测量它)

测试理论

在此输入图像描述

在gitHub上放了一个Magnet-O-Meter演示应用程序,它显示了一些差异.当应用程序运行并观察各种API如何反应时,在设备周围挥动磁铁是非常有启发性的:

CMMagnetometer对任何事情都没有太大的反应,除非你近距离地拉稀土磁铁.机载磁场似乎比局部外场或地球磁场更重要.在我的iPhone 4S上,它始终指向设备的左下角; 在iPad mini上它通常指向右上角.

CLHeading.[x | y | z] 对本地外部字段最敏感(响应),无论是相对于设备的移动还是静态.

(CMDevice)CMCalibratedMagneticField在面对不同的外部领域时是最稳定的,但是否则跟踪其核心位置对应的CLHeading.[x | y | z]非常接近.

CLHeading.magneticHeading - Apple对磁罗盘读取的建议 - 比任何这些都要稳定得多.它使用来自其他传感器的数据来稳定磁力计数据.但是你没有得到x,y,z的原始细分

             influenced by
             onboard fields    local external fields   earth's field
yellow               X                   X                 X
green                _                   X                 X
blue                 _                   _                 X
red                  _                   _                 X           
Run Code Online (Sandbox Code Playgroud)

CMMagnetometer
绿色CLHeading [X | Y | Z].
CMCalibratedMagneticField
CLHeading.magneticHeading

这似乎与文档相矛盾,这些文档表明CLHeading.[x | y | z]应该比CMCalibratedMagneticField更少受本地外部字段的影响.

你应该采取什么方法?基于我的有限测试,我建议......
如果你想要一个阅读
CLHeading的指南针magneticHeading,它trueHeading会给你最准确和最稳定的指南针读数.
如果你需要避免核心位置
CMDeviceMotion CMCalibratedMagneticField似乎是下一个最理想的,虽然相比稳定性和准确性要差得多magneticHeading.
如果您对局部磁场感兴趣,
CLHeading的'原始'xy和z属性似乎对局部磁场更敏感.
如果你想要所有数据包括板载磁场
原始磁力计数据来自CMMagnetometer.除非你准备进行大量的过滤,否则使用它并没有多大意义,因为它受到设备本身产生的磁场的巨大影响.

  • 这个答案对其彻底性没有足够的支持. (16认同)
  • @nhgrif - 感谢自愿赏金奖 - 你的亲切姿态确实令人惊叹! (4认同)