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

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

2)核心运动
CMMagneticFieldCMMotionManager中使用了magnetometerData.magneticField

问题:
a)两者之间有什么区别?我从两者中获得了不同的值(value)观。我期望它们将返回相同的值。
当我从静止位置(桌子朝上)启动应用程序,然后将设备向上抬起时,区别最为明显。
b)如果存在差异,什么时候应该使用“核心位置”标题中的磁场,什么时候应该使用“核心运动”中的磁场?

注意:我也不确定核心位置和核心运动的“磁场”是否指的是不同的磁场概念。
注意:对于两种方法,我都将强度计算为(x ^ 2 + y ^ 2 + z ^ 2)的平方根。

最佳答案

为了解决这个问题,我花了太多时间来研究Apple文档。

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

1/Core Motion framework
CMMotionManagers的 CMMagnetometer

2/Core Motion框架
CMDeviceMotion CMCalibratedMagneticField属性

3/Core Location framework
CLLocationManager的CLHeading
1/从磁力计提供“原始”数据。
2/和3/返回“派生”数据。两种情况下的数字相似(尽管不完全相同)。

Core Motion的CMMagnetometer和CMCalibratedMagneticField之间的差异

1/和2/-两者均来自Core Motion框架-区别如下:

CMDeviceMotion类引用

@property(readonly, nonatomic) CMCalibratedMagneticField magneticField



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

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

这些文档尚不清楚2/和3/之间的区别,但是它们确实生成了不同的数字,因此让我们进行一些挖掘……。

核心位置框架
CL标题

Location Awareness Programming Guide



以下是相关的CLHeading“原始”属性
@property(readonly, nonatomic) CLHeadingComponentValue x
@property(readonly, nonatomic) CLHeadingComponentValue y
@property(readonly, nonatomic) CLHeadingComponentValue z



我不清楚如何将微特斯拉测量值“规范化”(压缩?削波?)到+/- 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.

Core Motion框架
CMDeviceMotion CMC校准的磁场
/*
 *  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);

CM磁力计
 *  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



核心运动CMC校准磁场



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

1/CM磁力计
磁力计的原始读数

2/CMDeviceMotion(CMCalibratedMagneticField *)磁场
校正了磁力计读数,以消除设备偏差(板载磁场)

3/CLHeading [x | y | z]
校正了仪器偏置的磁力计读数并进行了滤波,以消除局部外部磁场(由设备移动检测到-如果磁场与设备一起移动,则忽略它;否则进行测量)

测试理论

我放了一个Magnet-O-Meter demo app on gitHub,其中显示了其中一些差异。在应用程序运行时在设备周围挥动磁铁并观察各种API的 react 是非常有启发性的:

除非您将稀土磁体拉近,否则CMMagnetometer不会对任何东西产生太大 react 。机载磁场似乎比本地外部磁场或地球磁场要重要得多。在我的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

黄色CM磁力计
绿色CLHeading。[x | y | z]
蓝色CMCalibratedMagneticField
红色CLHeading.magneticHeading

这似乎与文档相矛盾,这表明CLHeading。[x | y | z]受本地外部字段的影响应小于CMCalibratedMagneticField。

你应该采取什么方法?根据我的有限测试,我建议...
如果您想阅读指南针
CLHeading的magneticHeadingtrueHeading将为您提供最准确,最稳定的指南针读数。
如果您需要避开核心位置
CMDeviceMotion的CMCalibratedMagneticField似乎是下一个最受欢迎的方法,尽管它比magneticHeading不稳定和准确得多。
如果您对局部磁场感兴趣
CLHeading的“原始” x y和z属性似乎对局部磁场更为敏感。
如果您需要包括机载磁场在内的所有数据
来自CMMagnetometer的原始磁力计数据。除非您准备进行大量过滤,否则使用此方法实际上没有多大意义,因为它会受到设备本身产生的磁场的极大影响。

关于ios - 在iOS中,“核心位置”和“核心运动”框架的“磁场”值之间有什么区别?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15380632/

10-11 22:12