Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
742 views
in Technique[技术] by (71.8m points)

ios - CMDeviceMotion returns 0 values for magnetic field

I am developing iOS app with compass functionality. I have tried to use CMMagnetometerData updates which give uncalibrated, but normal results.

After that I tried to get CMDeviceMotion updates which turned out to give always zero magnetic field with CMMagneticFieldCalibrationAccuracyUncalibrated accuracy. The only device I have is an iPad, so can't test on others.

May be field is zero because sensor is not calibrated, but I could not find any way to perform calibration.

How to fix that?

UPDATE:

Here is suggested to use startDeviceMotionUpdatesUsingReferenceFrame:toQueue:withHandler:, however it didn't work for me.

Here is suggested to set showsDeviceMovementDisplay to true. However it didn't work either, calibration windows is just not popping up.

Finally, SOLVED. According to my observations:

1) Use startDeviceMotionUpdatesUsingReferenceFrame:toQueue:withHandler: with referenceFrame NOT equal to allZeros or XArbitraryZVertical.

2) Set showsDeviceMovementDisplay to true.

After few zero-value updates with accuracy CMMagneticFieldCalibrationAccuracyUncalibrated it will normalise.

CODE:

...
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)")
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Finally, according to my own observations:

1) Use startDeviceMotionUpdatesUsingReferenceFrame:toQueue:withHandler:with referenceFrame NOT equal to allZeros or XArbitraryZVertical.

2) Set showsDeviceMovementDisplay to true.

After few zero-value updates with accuracy CMMagneticFieldCalibrationAccuracyUncalibrated it will normalise.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...