Question

I'm logging the "attitude" value I get from CMMotionManager deviceMotion in a CADisplayLink callback (I have a need to perform an animation based on device rotation).

The values seem to "twitch" by a very large degree (upto 30%) every few milliseconds. This seems like a lot of shakiness and makes me wonder if I'm doing something wrong or if it's something with the device.

Please find logs below. The "Angle" printed is the "roll" component of "attitude", converted to degrees:


2013-04-10 00:07:12.683 MyApp[450:707] Angle: -92.91
2013-04-10 00:07:12.712 MyApp[450:707] Angle: -70.52
2013-04-10 00:07:12.714 MyApp[450:707] Angle: -92.25
2013-04-10 00:07:12.745 MyApp[450:707] Angle: -70.03
2013-04-10 00:07:12.747 MyApp[450:707] Angle: -91.74
2013-04-10 00:07:12.779 MyApp[450:707] Angle: -69.67
2013-04-10 00:07:12.784 MyApp[450:707] Angle: -91.23
2013-04-10 00:07:12.812 MyApp[450:707] Angle: -69.43
2013-04-10 00:07:12.815 MyApp[450:707] Angle: -91.19
2013-04-10 00:07:12.846 MyApp[450:707] Angle: -69.53
2013-04-10 00:07:12.849 MyApp[450:707] Angle: -91.33
2013-04-10 00:07:12.879 MyApp[450:707] Angle: -69.74
2013-04-10 00:07:12.881 MyApp[450:707] Angle: -91.57
2013-04-10 00:07:12.912 MyApp[450:707] Angle: -70.01
2013-04-10 00:07:12.915 MyApp[450:707] Angle: -91.85
2013-04-10 00:07:12.945 MyApp[450:707] Angle: -70.13
2013-04-10 00:07:12.949 MyApp[450:707] Angle: -91.99
2013-04-10 00:07:12.979 MyApp[450:707] Angle: -70.03
2013-04-10 00:07:12.983 MyApp[450:707] Angle: -91.93
2013-04-10 00:07:13.012 MyApp[450:707] Angle: -69.76
2013-04-10 00:07:13.016 MyApp[450:707] Angle: -91.71
2013-04-10 00:07:13.046 MyApp[450:707] Angle: -69.34
2013-04-10 00:07:13.051 MyApp[450:707] Angle: -91.19
2013-04-10 00:07:13.079 MyApp[450:707] Angle: -68.89
2013-04-10 00:07:13.082 MyApp[450:707] Angle: -90.94
2013-04-10 00:07:13.112 MyApp[450:707] Angle: -68.52
2013-04-10 00:07:13.114 MyApp[450:707] Angle: -90.66
2013-04-10 00:07:13.151 MyApp[450:707] Angle: -67.85
2013-04-10 00:07:13.156 MyApp[450:707] Angle: -89.47
2013-04-10 00:07:13.179 MyApp[450:707] Angle: -65.66
2013-04-10 00:07:13.181 MyApp[450:707] Angle: -88.10
2013-04-10 00:07:13.212 MyApp[450:707] Angle: -63.81
2013-04-10 00:07:13.216 MyApp[450:707] Angle: -86.33
2013-04-10 00:07:13.245 MyApp[450:707] Angle: -61.07
2013-04-10 00:07:13.248 MyApp[450:707] Angle: -83.63
2013-04-10 00:07:13.279 MyApp[450:707] Angle: -58.95
2013-04-10 00:07:13.282 MyApp[450:707] Angle: -81.46
2013-04-10 00:07:13.312 MyApp[450:707] Angle: -56.71
2013-04-10 00:07:13.314 MyApp[450:707] Angle: -79.06
2013-04-10 00:07:13.346 MyApp[450:707] Angle: -53.29
2013-04-10 00:07:13.350 MyApp[450:707] Angle: -75.23
2013-04-10 00:07:13.380 MyApp[450:707] Angle: -51.63
2013-04-10 00:07:13.383 MyApp[450:707] Angle: -73.37
2013-04-10 00:07:13.414 MyApp[450:707] Angle: -50.35
2013-04-10 00:07:13.418 MyApp[450:707] Angle: -72.11
2013-04-10 00:07:13.446 MyApp[450:707] Angle: -50.08
2013-04-10 00:07:13.450 MyApp[450:707] Angle: -72.01
2013-04-10 00:07:13.479 MyApp[450:707] Angle: -50.50
2013-04-10 00:07:13.488 MyApp[450:707] Angle: -73.51
2013-04-10 00:07:13.512 MyApp[450:707] Angle: -51.25
2013-04-10 00:07:13.514 MyApp[450:707] Angle: -74.14
2013-04-10 00:07:13.545 MyApp[450:707] Angle: -49.98
2013-04-10 00:07:13.547 MyApp[450:707] Angle: -72.96
2013-04-10 00:07:13.579 MyApp[450:707] Angle: -46.99
2013-04-10 00:07:13.582 MyApp[450:707] Angle: -68.58
2013-04-10 00:07:13.612 MyApp[450:707] Angle: -43.01
2013-04-10 00:07:13.616 MyApp[450:707] Angle: -65.32
2013-04-10 00:07:13.645 MyApp[450:707] Angle: -40.92
2013-04-10 00:07:13.647 MyApp[450:707] Angle: -62.80
2013-04-10 00:07:13.680 MyApp[450:707] Angle: -39.70
2013-04-10 00:07:13.683 MyApp[450:707] Angle: -61.30
2013-04-10 00:07:13.712 MyApp[450:707] Angle: -40.74
2013-04-10 00:07:13.714 MyApp[450:707] Angle: -63.06
2013-04-10 00:07:13.745 MyApp[450:707] Angle: -42.29
2013-04-10 00:07:13.747 MyApp[450:707] Angle: -65.68
2013-04-10 00:07:13.779 MyApp[450:707] Angle: -43.18
2013-04-10 00:07:13.780 MyApp[450:707] Angle: -67.58
2013-04-10 00:07:13.812 MyApp[450:707] Angle: -42.13
2013-04-10 00:07:13.815 MyApp[450:707] Angle: -66.35
2013-04-10 00:07:13.845 MyApp[450:707] Angle: -40.95
2013-04-10 00:07:13.848 MyApp[450:707] Angle: -64.67
2013-04-10 00:07:13.879 MyApp[450:707] Angle: -39.73
2013-04-10 00:07:13.881 MyApp[450:707] Angle: -62.90
2013-04-10 00:07:13.913 MyApp[450:707] Angle: -40.06
2013-04-10 00:07:13.916 MyApp[450:707] Angle: -63.12
2013-04-10 00:07:13.947 MyApp[450:707] Angle: -40.78
2013-04-10 00:07:13.949 MyApp[450:707] Angle: -63.39
2013-04-10 00:07:13.979 MyApp[450:707] Angle: -41.51
2013-04-10 00:07:13.981 MyApp[450:707] Angle: -62.78
2013-04-10 00:07:14.012 MyApp[450:707] Angle: -42.06
2013-04-10 00:07:14.014 MyApp[450:707] Angle: -61.77
2013-04-10 00:07:14.045 MyApp[450:707] Angle: -43.89
2013-04-10 00:07:14.047 MyApp[450:707] Angle: -61.02
2013-04-10 00:07:14.079 MyApp[450:707] Angle: -45.41
2013-04-10 00:07:14.080 MyApp[450:707] Angle: -61.20
2013-04-10 00:07:14.112 MyApp[450:707] Angle: -46.93
2013-04-10 00:07:14.114 MyApp[450:707] Angle: -61.53
2013-04-10 00:07:14.146 MyApp[450:707] Angle: -49.21
2013-04-10 00:07:14.147 MyApp[450:707] Angle: -62.76
2013-04-10 00:07:14.179 MyApp[450:707] Angle: -51.34
2013-04-10 00:07:14.182 MyApp[450:707] Angle: -64.51
2013-04-10 00:07:14.212 MyApp[450:707] Angle: -53.39
2013-04-10 00:07:14.214 MyApp[450:707] Angle: -66.41
2013-04-10 00:07:14.245 MyApp[450:707] Angle: -56.29
2013-04-10 00:07:14.248 MyApp[450:707] Angle: -69.30
2013-04-10 00:07:14.279 MyApp[450:707] Angle: -57.85
2013-04-10 00:07:14.280 MyApp[450:707] Angle: -70.88
2013-04-10 00:07:14.312 MyApp[450:707] Angle: -60.23

The angle measured is "flickering" by almost 20 degrees every few milliseconds. Based on what I'd read about CoreMotion so far, I was expecting errors but not of THIS range.

Could I possibly be doing something wrong - am I not measuring the right thing?



Edit: Code below - sorry for the formatting. Both "code" and "blockquote" don't seem to work properly.


//I'm letting the user laze around a bit before starting the motion updates.
//At the moment this is in the form of a naive idle timer which is fired after
//the first 9 seconds of launching the app (just cause)


- (void)didFireIdleTimer:(id)theTimer {

[mReferenceAttitude release];
mReferenceAttitude = [[[sSharedMotionManager deviceMotion] attitude] retain];

[self stopIdleTimer];
}

//sSharedMotionManager is an instance of CMMotionManager

//Then, I'm setting up a display link callback wherein the "current" deviceMotion
//is retrieved every time and the difference between the current "attitude"
//and reference "attitude" calculated. It is this difference that is
//converted to degrees and printed

//This is the display link callback, lazily named. :)
- (void)didRefreshScreen:(id)sender {

CMAttitude *thisAttitude = [[sSharedMotionManager deviceMotion] attitude];
[thisAttitude multiplyByInverseOfAttitude:mReferenceAttitude];

NSLog(@"Angle: %0.2f", thisAttitude.roll * 180 / 3.14159);

//Rest of the code
//....
}
Was it helpful?

Solution

Few hours of testing confirms that the issue arose because of deviceMotionUpdateInterval not being set on the CMMotionManager instance. Setting it to 1.0/60.0 (or any other valid value) fixes this "flickering" and results in the values changing smoothly.

OTHER TIPS

Looking at the values I notice that the series of every second measurement seems to be alright. That means 1, 3, 5, 7, ... and 2, 4, 6, 8, ... are bulding stable sequences. In most cases this indicates that 2 instances are running or the reference attitude is toggled.

here is my code to avoid flickering in may app:

float xAxis,yAxis, zAxis;
xAxis = self.manager.accelerometerData.acceleration.x;
yAxis = self.manager.accelerometerData.acceleration.y;
zAxis = self.manager.accelerometerData.acceleration.z;

// returns if the phone is lying on the table:
if (zAxis < -0.8 || zAxis > 0.8) return;

CGFloat angle =  atan2f(xAxis, yAxis ); // The angle!!!

float noise = 0.011; // Flicker noise (the noise you want to filter)

// max and min are global variables
if (angle > max){
    max = angle;
    min = max - noise;
}
if (angle < min){
    min = angle;
    max = min + noise;
}

// Average: (no flickering):
angle = min + (max - min) / 2.0;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top