问题
I'm trying to use iDevice's attitude self.motionManager.deviceMotion.attitude.quaternion
the device is resting on the table, but the values are not the same. how to stabilise these values without causing bad rotation? I'm using the device attitude to rotate the camera node.
(x = -0.0055437298906573507, y = -0.0078092851375721247, z = -0.041180405121897398, w = 0.999105828407855)
(x = -0.0061666945840810842, y = -0.0067849414785486747, z = -0.041464744435584115, w = 0.99909789881469635)
(x = -0.0057767614213563457, y = -0.0075097232630314727, z = -0.041803806548186787, w = 0.99908091506248087)
(x = -0.0054897030127900098, y = -0.0077124534854605253, z = -0.04219926058901851, w = 0.99906436410664467)
(x = -0.0052714642886002782, y = -0.0078368692177714049, z = -0.042675299607953819, w = 0.99904435034111316)
(x = -0.0050140321661910547, y = -0.0078121993123853265, z = -0.043041870709832147, w = 0.99903014288315972)
(x = -0.0050055928591862253, y = -0.0077335374133680208, z = -0.043505056503552082, w = 0.99901073392523531)
(x = -0.0049666831093899792, y = -0.007717140215596976, z = -0.043913562364765651, w = 0.99899318158145256)
(x = -0.0047768022686966614, y = -0.0078160798819143576, z = -0.044274861496884942, w = 0.99897739098280313)
(x = -0.0047310514463435671, y = -0.0078007790545880336, z = -0.044670164461142137, w = 0.9989601300379195)
(x = -0.004618244779613233, y = -0.0078641769042355775, z = -0.045003270721875412, w = 0.99894520978936451)
(x = -0.0049526705779270597, y = -0.0076127708990477733, z = -0.045411652395276572, w = 0.99892707371465494)
(x = -0.0053219441444451315, y = -0.0074858231291817018, z = -0.045723089011719641, w = 0.99891192729581401)
(x = -0.0056345717154138147, y = -0.0073613453524927486, z = -0.046005287981812061, w = 0.99889818083421522)
(x = -0.0056064974434034201, y = -0.0074105820596984404, z = -0.046130222648849362, w = 0.99889221291304886)
(x = -0.0053487406143112462, y = -0.0076910190187535112, z = -0.046331716108766401, w = 0.99888218088156866)
self.motionManager = [[CMMotionManager alloc] init];
self.motionManager.deviceMotionUpdateInterval = 1.0/20.0;
[self.motionManager startDeviceMotionUpdates];
回答1:
What you're looking for is a low pass filter — a way to separate the high frequency signals in a sensor input (noise, random jiggling) from the low frequency ones (deliberate user motion).
The typical formula for a real-time filter goes like this:
newValue = (sampledValue * factor) + (lastValue * (1 - factor))
That is, you get newValue (the filtered input you're going to use) from the linear interpolation of sampledValue (the raw input from the sensor) and lastValue (the newValue computed on the previous time step; be sure to initialize it to something sensible on the first computation), with a factor that controls how far along the blend is. You can tweak factor to control how much signal gets through your filter.
You could probably apply this formula separately to each of the x, y, z, and w components of a quaternion and get a vaguely passable result. But a) writing the same code four times isn't so fun, and b) quaternions have some special math that'll cause this method to break down over time.
Instead, you can make your CMQuaternion
into a GLKQuaternion
and do the blending in one call to GLKQuaternionSlerp. (And it minds the special math for you.)
filteredAttitude = GLKQuaternionSlerp(lastAttitude, sampledAttitude, factor)
Then make an SCNQuaternion
from your GLKQuaternion
and you can set the orientation of your node.
来源:https://stackoverflow.com/questions/27660653/idevice-attitude-stabilising-quaternion