Compensating for Broken GyroScopes?

Hello Everyone,


I'm posting this with the hope of gaining some clarity both for myself and future developers who may encounter this issue when trying to use rotationRate data from the CMMotionManager Class.


The game I've been developing uses motionManager.gyroData.rotationRate.y as it's main input, using the value to steer a vehicle.


It seems to work well on my device, which to my knowledge has never been dropped in it's full year of normal use.


The code looks like this:


if (self.motionManager.gyroData.rotationRate.y > .15 || self.motionManager.gyroData.rotationRate.y < -.15) {
[[self Rover] runAction:[SKAction moveByX:(_TiltSensitivity * (CGFloat)self.motionManager.gyroData.rotationRate.y) y:0 duration:.2]];
}


_TiltSensitivity is simply a number (Limited to being between 10 and 50 for this app) which takes the output in Radians and moves the device by the resulting amount after multiplication.


rotationRate.y is normally a floating point number accurate to 6 points past the decimal. (x.xxxxxx).


During testing the nominal output when laying flat on a table wavers around -.01xxxx, where xxxx represents the "dancing" numbers. Passing in this number would cause the vehicle to steer left slightly.


In a perfect world, when laying still, that output should be 0, with a positive or negative number indicating movement. With that in mind I programmed a small threshold to compensate for real world behavior. (Shown Above)


That code produced a vehicle that didn't move and was ready for "real" input, to which it responded beautifully.


However, it seems like different devices have different nominal output depending on the stresses endured by the sensor during it's lifetime.


Before today, the .15 in the code was .02.




After testing on a few different devices, including my iPhone 5C, and a neighbors iPhone 6 and iPad Mini, the vehicle response was perfect. (Using .02)


Today I took the code to work in order to take video snapshots for the App Preview from an iPhone 6 Plus and an iPad Air.


The results from those were vehicles which veered in the direction of bias for the particular device.


The iPhone 6 Plus produced output of -.05xxxx, causing the vehicle to steer slightly left on a flat table.


The iPad Air produced output of .11xxxx, causing the vehicle to veer heavily to the right.


My device still produced it's normal output under the same conditions.


After coming home and doing some testing, it seemed like .15 was the highest number I could set as a threshold without the vehicle becoming annoyingly unresponsive for minute movements.


The iPhone 6 Plus owner is certain the the phone has taken a few hard falls. I didn't have a chance to ask the iPad Air Owner.


This app has been tested thoroughly for 4 months, and has even passed the App Review twice. (I'm not sure if App Review tests the actual gameplay to ensure a good experience on all devices).


I've submitted this latest build with the modified code provided above in the hopes that most devices will produce normal output beneath the threshold when being held still. Since the code still functions well on my device, and theoreticaly this threshold should eliminate the behavior on the two bad devices I mentioned, it seems like the problem may be solved.


The app is scheduled for release on August 1st, if all goes well, however my fear is that certain people will still experience this problem and give the app bad ratings. I've tried as mentioned to find the best possible threshold that doesn't compromise responsiveness, because the alternate solution would be a calibration which I'm confident could work but would be found cumbersome by most users, especially the extremely young demographic which probably can't even spell or understand the word "calibration". (4 year olds who could otherwise play the game without knowing how to read)


Also, the reason I'm not using the Quaternion method is because I wanted the app to have a "steering wheel" response, and not a sliding experience.


I could also be completely wrong about what's really happening, but having the code work perfectly on the first 3 devices and having the App pass Review led me to beleive I must be dealing with something out of the ordinary working order on the two devices mentioned. (I haven't been able to get my hands on more devices to test with).


Any insight into this would be appreciated.


Regards,

WareChameleon

Replies

>I'm not sure if App Review tests the actual gameplay to ensure a good experience on all devices.

App Review isn't a testing service. That's what Testflight is for.

Thanks for the insight.


Today I confirmed that the update to .15 eliminated the behavior mentioned for those devices.


I was also able to test on a few more phones, and all of them so far had normal output of around .01. (3 more tested)


Hopefully this will help others who need a similar function for their game/apps.

You still need to provide a means to calibrate the device for your app. Failing that,

you will get odd results on some devices from time to time.

Thanks for responding.


As an update, the filter seems to have withstood the test of time.


The calibration of sensitivity by providing a UISlider in an options menu has sufficed to let users choose how the gyroscope reacts.


As a note, on tvOS (Siri Remote) Apple seems to be aware of the need for a filter so they took care of that compensation in the background.


(One of the WWDC talks mentions this specifically)