CMDeviceMotion返回磁场数值为0的问题

9
我正在开发带有指南针功能的iOS应用程序。我尝试使用CMMagnetometerData更新,这些更新提供未校准但正常的结果。
之后,我尝试获取CMDeviceMotion更新,结果始终为零磁场,并且具有CMMagneticFieldCalibrationAccuracyUncalibrated精度。我只有一个iPad设备,因此无法在其他设备上进行测试。
可能磁场为零是因为传感器未校准,但我找不到任何执行校准的方法。
如何解决这个问题?
更新: 在这里建议使用startDeviceMotionUpdatesUsingReferenceFrame:toQueue:withHandler:,但对我没有用。 在这里建议将showsDeviceMovementDisplay设置为true。但它也没有起作用,校准窗口只是没有弹出。
最后,问题已解决。根据我的观察:
1)使用referenceFrame不等于allZerosXArbitraryZVerticalstartDeviceMotionUpdatesUsingReferenceFrame:toQueue:withHandler:
2)将showsDeviceMovementDisplay设置为true
在几次精度为CMMagneticFieldCalibrationAccuracyUncalibrated的零值更新后,它将被归一化。 代码:
...
motionManager.deviceMotionUpdateInterval = 0.05
motionManager.showsDeviceMovementDisplay = true 
motionManager.startDeviceMotionUpdatesUsingReferenceFrame(CMAttitudeReferenceFrame.XArbitraryCorrectedZVertical, toQueue: NSOperationQueue.mainQueue(), withHandler:handleUpdate)
...
private func handleUpdate(data: CMDeviceMotion!, error: NSError!) {
    if data != nil {
        let field = data.magneticField.field
        println("\(field.x), \(field.y), \(field.z)")
    }
}

请分享你的代码。 - 9to5ios
2个回答

13

最后,根据我的观察:

1)使用startDeviceMotionUpdatesUsingReferenceFrame:toQueue:withHandler:,其中referenceFrame不等于allZerosXArbitraryZVertical

2)将showsDeviceMovementDisplay设置为true

几次精度为CMMagneticFieldCalibrationAccuracyUncalibrated的零值更新之后,它将被规范化。


3
感谢您回答自己的问题。这真的在我的情况下帮了我! - Michael Ramos

0

更新此解决方案以适用于Swift 5.6.1。

以下代码还展示了如何一起读取其他运动数据。

data!. magneticField.accuracy.rawValue返回的内容将不是-1。

代码:

// MARK: gyroscope acceleration magnitude orientation gravity all-at-once
motionManager.deviceMotionUpdateInterval = 0.01
// for calibrated magnetic field
motionManager.showsDeviceMovementDisplay = true
motionManager.startDeviceMotionUpdates(using: CMAttitudeReferenceFrame.xArbitraryCorrectedZVertical, to: OperationQueue.main) { (data, error) in
    // handle device motion updates
    if isPlaying {
        if timeT.isEmpty {
            startTime = data!.timestamp
        }
        timeT.append(data!.timestamp - startTime)
        // get gyroscope sensor data
        gyroX.append(data!.rotationRate.x)
        gyroY.append(data!.rotationRate.y)
        gyroZ.append(data!.rotationRate.z)
        // get accelerometer sensor data
        accX.append(data!.userAcceleration.x)
        accY.append(data!.userAcceleration.y)
        accZ.append(data!.userAcceleration.z)
        // get magnetometer sensor data
        // data!.magneticField.accuracy
        magX.append(data!.magneticField.field.x)
        magY.append(data!.magneticField.field.y)
        magZ.append(data!.magneticField.field.z)
        // get attitude orientation
        oriPitch.append(data!.attitude.pitch)
        oriYaw.append(data!.attitude.yaw)
        oriRoll.append(data!.attitude.roll)
        // get gravity vector
        // motion.gravity.x
        // motion.gravity.y
        // motion.gravity.z
        
        // debug
        print(data!.timestamp - startTime)
        print(data!.rotationRate)
        print(data!.userAcceleration)
        print(data!.magneticField.accuracy.rawValue)
        print(data!.magneticField.field)
        print(data!.attitude)
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接