Jump to content

technique for smooth phone rotation data?


Recommended Posts

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. 

Link to post
Share on other sites

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.

Link to post
Share on other sites
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

Link to post
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...