我有两种方法可以使用iOS设备的磁力计获得磁场(强度,x,y和z)。
1)核心位置
使用CLLocationManagerDelegate
方法locationManager:didUpdateHeading:
中的CLHeading。这类似于Apple的Teslameter示例应用程序。
2)核心动作
来自CMMagneticField
的{{1}}使用CMMotionManager
。
问题:
a)两者有什么区别?我从两者中得到了不同的价值观。我期待他们会返回相同的值
当我从静止位置(面朝上的桌子)启动应用程序,然后将设备向上提升到空中时,差异最显着。
b)如果存在差异,何时应使用Core Location标题中的磁场,何时使用Core Motion的磁场?
注意:我也不确定Core Location和Core Motion的“磁场”是否涉及不同的磁场概念。
注意:我将强度计算为两种方法的平方根(x ^ 2 + y ^ 2 + z ^ 2)。
答案 0 :(得分:174)
为了解开这个问题,我花了太多时间挖掘Apple文档。
获取磁力计数据有三种方法
1 / Core Motion framework
CMMotionManagers的CMMagnetometer
课程
2 / Core Motion框架
CMDeviceMotion CMCalibratedMagneticField
属性
3 / Core Location framework
CLLocationManager' s CLHeading
1 /供应' raw'来自磁力计的数据 2/3 / return'派生'数据。两种情况下的数字相似(尽管不完全相同)。
Core Motion的CMMagnetometer和CMCalibratedMagneticField之间的区别
来自Core Motion框架的1 /和2 / - 不同如下:
CMDeviceMotion类参考
@property(readonly, nonatomic) CMCalibratedMagneticField magneticField
讨论
此属性返回的CMCalibratedMagneticField可为您提供设备附近的总磁场,而无需设备偏差。与CMMagnetometer类的magneticField属性不同,这些值反映了地球的磁场加上周围的场,减去了设备偏差。
CMMagnetometer为我们提供原始数据,CMCalibratedMagneticField是调整后的数据。
Core Motion的CMCalibratedMagneticField和Core Location的CLHeading之间的区别
对于2 /和3 /之间的差异,文档并不是立即明确的,但是它们会产生不同的数字,所以让我们进行一些挖掘......
核心位置框架
CLHeading
来自Location Awareness Programming Guide
获取与标题相关的事件
在包含磁力计的设备上运行的应用可以使用标题事件。磁力计测量从地球发出的附近磁场,并使用它们来确定设备的精确方向。虽然磁力计可能会受到局部磁场的影响,例如音频扬声器,电机和许多其他类型的电子设备中的固定磁铁所产生的磁场,但核心位置足够智能,可以滤除随设备移动的磁场。
以下是相关的CLHeading
' raw'属性
@property(readonly, nonatomic) CLHeadingComponentValue x
@property(readonly, nonatomic) CLHeadingComponentValue y
@property(readonly, nonatomic) CLHeadingComponentValue z
[x | y | z]轴的地磁数据(以微格式测量)。 (只读)
该值表示与设备跟踪的磁场线的[x | y | z]轴偏差。 (旧版本的文档添加:)此属性报告的值已标准化为-128到+128。
我不清楚microtesla测量如何被标准化' (压缩?剪裁?)到+/- 128的范围,仍然代表它声称要测量的单位。也许这就是为什么从文档中删除句子的原因。 iPad mini上的单元似乎符合这种范围,但iPhone4S可以在更高的范围内提供 CMMagnetometer 读数,例如200-500。
API显然希望您使用派生属性:
@property(readonly, nonatomic) CLLocationDirection magneticHeading
@property(readonly, nonatomic) CLLocationDirection trueHeading
以度为单位给出稳定的N / S E / 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.
核心动作框架
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 *)magneticField
磁控计读数校正了器件偏置(板载磁场)
3 / CLHeading [x | y | z]
磁控计读数针对设备偏差进行了校正,并进行了滤波以消除局部外部磁场(通过设备移动检测到 - 如果磁场随设备移动,忽略它;否则测量它)
测试理论
我放了一个显示其中一些差异的Magnet-O-Meter demo app on gitHub。当应用程序运行并观察各种API如何反应时,在设备周围挥动磁铁是非常有启发性的:
CMMagnetometer 对任何事情都没有多大反应,除非你近距离地拉稀土磁铁。机载磁场似乎比局部外场或地球磁场更重要。在我的iPhone 4S上,它始终指向设备的左下角;在iPad mini上它通常指向右上角。
CLHeading。[x | y | z] 是本地外部字段中最易受攻击的(响应式),无论是相对于设备的移动还是静态。
(CMDevice) CMCalibratedMagneticField 面对不同的外部领域是最稳定的,但是否则跟踪它的核心位置对应 CLHeading。[x | y | z] < / em>非常接近。
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
黄色 CMMagnetometer
绿色 CLHeading。[x | y | z]
blue CMCalibratedMagneticField
红色 CLHeading.magneticHeading
这似乎与文档相矛盾,这些文档暗示 CLHeading。[x | y | z] 应该比 CMCalibratedMagneticField 更少受本地外部字段的影响。
你应该采取什么方法?基于我的有限测试,我建议...
如果您想要指南针阅读
CLHeading&#39; magneticHeading
和trueHeading
将为您提供最准确,最稳定的指南针读数。
如果您需要避免核心位置
CMDeviceMotion CMCalibratedMagneticField
似乎是下一个最理想的,尽管比magneticHeading
稳定得多且准确得多。
如果您对当地的磁场感兴趣
CLHeading&#39; raw&#39; x y和z属性似乎对局部磁场更敏感
如果您想要所有数据,包括板载磁场
来自CMMagnetometer的原始磁力计数据。除非你准备进行大量的过滤,否则使用它并没有多大意义,因为它受到设备本身产生的磁场的巨大影响。
答案 1 :(得分:1)
这个答案是基于我对下面文档链接的解释
a)CLHeading是“偏离与设备跟踪的磁场线”,而磁力计Data.magneticField“是设备观察到的总磁场等于地球的地磁场加上从设备本身及其周围环境引入的偏差“。
因此,CLHeading为您提供过滤值,其中参照系是地球的现有磁场。虽然magnetometerData为您提供未经过滤的值,但参考框架是设备。
b)如果你在想要知道哪里是磁性或真北的位置做任何事情,我建议使用CLHeading。如果你想创建一个响应附近设备磁场的应用程序,或者你想要执行一些特定的传感器融合,可能尝试创建一个AHRS,然后使用CMMagneticField。答案 2 :(得分:1)
使用CLHeading时要记住的重要事项。[x | y | z]值来计算局部磁场强度是CLLocationManagerDelegate方法
应设置为返回YES。我发现如果关闭此校准警告,磁力计读数永远不会校准,因此当设备的方向改变时,计算的场强非常不稳定。
答案 3 :(得分:0)
我认为磁力计Data.magneticField它告诉你加速度,而不是位置(因此为什么你会让大值从静止移动到移动),而位置管理器提供有关设备指向的方向的数据。