2

I've got Core Motion manager in my iOS app:

motionManager = [[CMMotionManager alloc] init];
motionManager.deviceMotionUpdateInterval = 1.0 / 60.0;
if ([motionManager isDeviceMotionAvailable]) {
    [motionManager startDeviceMotionUpdates];
}

and in update method (I'm using cocos3d, but it does not matter) I've got this:

-(void) updateBeforeTransform:(CC3NodeUpdatingVisitor *)visitor
{
    if (motionManager.deviceMotionActive)
    {
        CMDeviceMotion *deviceMotion = motionManager.deviceMotion;
        CMAttitude *attitude = deviceMotion.attitude;

        NSLog(@"%f, %f, %f", attitude.yaw, attitude.pitch, attitude.roll);

    }
}

I put device on table and start to watch yaw, pitch and roll values, and the yaw is constantly changing! it is changing for about 10 degrees in couple of minutes, and it is absolutely inadmissibly in my app. What is the reason of that changing and how can I avoid it? I started to think that it happens because of Earth rotation, but the speed is too much :)

Thanks in advance!

medvedNick
  • 4,512
  • 4
  • 32
  • 50
  • 1
    Do you have a compass in the device? If you don't then it makes perfect sense. – Ali Jul 26 '12 at 09:00
  • I'm using iPad 3 now, I think it has a compass. Actually, this app is Augmented Reality app, and I have already done with rotation cocos3d scene with rotation of the device, all works great except this slowly but constantly changing yaw angle – medvedNick Jul 26 '12 at 09:10
  • Please make sure whether you have a compass. The gyros can take care of the rotations in the short run, and for fast rotations. What you describe is typical for devices without a compass. – Ali Jul 26 '12 at 09:17
  • @Kay do you know how can I access North heading independently from my Core Motion Manager? I've tried CLLocation manager and it's property "heading", but it did not change so fast as the yaw angle – medvedNick Jul 26 '12 at 11:41
  • @medvedNick Look at [Which iOS class/code returns the magnetic North?](http://stackoverflow.com/questions/11383968/which-ios-class-code-returns-the-magnetic-north/11384054#11384054) – Kay Jul 26 '12 at 13:29

2 Answers2

3

Let me try a shot in the dark. With iOS 5 magnetometer data is part of the Core Motion sensor fusion algorithm. For many applications like games there is no need or better is's dangerous because of increased energy consumption and the possible need to calibrate the compass forcing the user to do this 8 like motion.

So I speculate that compass data is considered within sensor fusion only if explicitly stated by using CMMotionManager's startDeviceMotionUpdatesUsingReferenceFrame instead of startDeviceMotionUpdates. Try out CMAttitudeReferenceFrameXMagneticNorthZVertical and check if the drifting effect decreases.

Kay
  • 12,918
  • 4
  • 55
  • 77
  • well, it has almost solved the problem... Now it is looking like that: yaw is slowly changing as usual, but after 5 or so seconds it jumps to the right value. Then, it starting to change again and after 5 secs it again jumps to the right value... I saw this on the Apple's documentation: "CMAttitudeReferenceFrameXArbitraryCorrectedZVertical Describes the same reference frame as CMAttitudeReferenceFrameXArbitraryZVertical except that the magnetometer, when available and calibrated, is used to improve long-term yaw accuracy" this looks like what I wanted, but it does not decrease drift.. – medvedNick Jul 27 '12 at 08:23
  • PS: CMAttitudeReferenceFrameXArbitraryCorrectedZVertical doing like the CMAttitudeReferenceFrameXMagneticNorthZVertical - yaw is changing and then jumping to the right value – medvedNick Jul 27 '12 at 08:26
  • @medvedNick Try out a different location for testing, just to be sure that there are no disturbing magnetic fields around. Maybe [Sensor Monitor](http://itunes.apple.com/us/app/sensor-monitor/id381075251?mt=8) (it's free) can help you to check if your sensors are OK. – Kay Jul 27 '12 at 08:31
  • hmm I'll try.. I've noticed, that in some time yaw drift is decreasing.. maybe it need time to calibrate itself. Thanks for help, anyway! :) – medvedNick Jul 27 '12 at 08:37
3

What you are experiencing is something called drift and you can't do much about it.

Basically, the gyroscope is very good at measuring rotational rates but it cannot measure instantaneous orientations. Therefore, in order to calculate the current orientation of the device, a sensor algorithm must integrate sensed rates into positions. However, as positions are calculated, small errors build up over time and the computed orientation may drift, even if the device remains mostly still.

If a device happens to have a sensor that can measure instantaneous orientations, such as a magnetometer, then a sensor fusion algorithm can correct the drift by comparing / combining sensor inputs, hence Apple's reference frame option: CMAttitudeReferenceFrameXArbitraryCorrectedZVertical.

But Apple's implementation isn't perfect, that's why you see the massive jumps back and forth to correct build up of error when CMAttitudeReferenceFrameXArbitraryCorrectedZVertical is enabled. A better algorithm might be one that at least smooths out the error correction over time.

Colin
  • 41
  • 3