iDevice attitude: stabilising quaternion

大憨熊 提交于 2019-12-08 12:54:55

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!