ikaruga Posted August 28, 2021 Share Posted August 28, 2021 I'm using the `deviceorientation` event to get phone rotation data. And I'm noticing that at least on my device the rotation data is very "jumpy". That is it can look something like this: 0 -10 0 1 2 4 40 20 Have not had a change to try the Gyroscope API but I imagine it has the same limitation. My question is, does any one know of a technique to smooth of the rotation data. So in the above example, it would be `0, 0, 1, 2, 4, 20`. The use case is that when a user rotates the phone to the left/right, the app would apply a force vector. But with jumpy data like the above, the result isn't a smooth experience. Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted August 28, 2021 Share Posted August 28, 2021 honestly , with all those threads about gyroscope someone has to make pixi-gyro plugin. Want to try? Quote Link to comment Share on other sites More sharing options...
Exca Posted August 30, 2021 Share Posted August 30, 2021 Measure N samples, calculate the average from those and you get a much smoother result. So something like: const buffer = []; const sampleCount = 10; ... // Later somewhere in measuring function const sample = data from gyro buffer.push(sample); while(buffer.length > sampleCount) buffer.shift(); return { x: buffer.map( sample => sample.x).reduce( (a,b)=>a+b)/sampleCount, y: buffer.map( sample => sample.y).reduce( (a,b)=>a+b)/sampleCount, z: buffer.map( sample => sample.z).reduce( (a,b)=>a+b)/sampleCount }; I'm using just a simple map/reduce -combination in there, if you would like it to be most efficient js can handle then having a continuous avg counter would be better. Also applying a smoothing curve instead of flat average might produce more responsive feeling results while still keeping a smooth result. Quote Link to comment Share on other sites More sharing options...
ikaruga Posted August 30, 2021 Author Share Posted August 30, 2021 6 hours ago, Exca said: Measure N samples, calculate the average from those and you get a much smoother result. So something like: const buffer = []; const sampleCount = 10; ... // Later somewhere in measuring function const sample = data from gyro buffer.push(sample); while(buffer.length > sampleCount) buffer.shift(); return { x: buffer.map( sample => sample.x).reduce( (a,b)=>a+b)/sampleCount, y: buffer.map( sample => sample.y).reduce( (a,b)=>a+b)/sampleCount, z: buffer.map( sample => sample.z).reduce( (a,b)=>a+b)/sampleCount }; I'm using just a simple map/reduce -combination in there, if you would like it to be most efficient js can handle then having a continuous avg counter would be better. Also applying a smoothing curve instead of flat average might produce more responsive feeling results while still keeping a smooth result. No a moving average doesn't work. I had better success with a low pass filter. Will post links and code in a few Quote Link to comment Share on other sites More sharing options...
ikaruga Posted August 30, 2021 Author Share Posted August 30, 2021 This technique has been working: http://phrogz.net/js/framerate-independent-low-pass-filter.html Basically, it's just: newValue += (prevValue - newValue) / smoothing; I'm using smoothing = 30. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.