Saturday, October 8, 2011

Shake It Like a High Pass Filter

Hey everyone,

Last week, I got my feet wet with the iPhone accelerometer and compass data. To get started, I checked out some sample code from Apple's iOS Developer Library. I decided to use the AccelerometerGraph sample code as a basis for my code. 
The AccelerometerGraph app in action. AccelerometerGraph shows two graphs, one of the raw data , and one of the filtered data.
AccelerometerGraph samples the X, Y, and Z accelerometers at 60Hz (displayed as Red, Green, and Blue, respectively). The acceleration values are measured in units of g-force, with a value of 1.0 approximately equal to gravity acting on that axis of the phone.There was no minimum acceleration threshold in the original app; every second exactly 60 measurements were logged and graphed. The app provides options for Low Pass/High Pass and Standard/Adaptive filtering. Low pass filters allow the lower values to go through, while filtering out the higher values. In terms of acceleration, this means that quick, sharp movements will be filtered out, while steady sources of acceleration like gravity or larger movements will show up in the graph. High pass filters do the opposite. They allow the higher values to go through while filtering out the lower values, which means that the effects of gravity will be filtered out, leaving just the shorter, sharper movements in the graph. An adaptive filter is one that self-adjusts based on an error signal to attenuate noise while leaving the original signal intact.

When modifying AccelerometerGraph for gesture recognition, I added a minimum threshold. Any measurement where none of the accelerometers recorded a value higher than 0.05 was thrown out. The Adaptive High Pass Filter worked the best for filtering out both the effects of gravity and of small incidental movements like shifting from side to side. The image above shows the Adaptive High Pass Filter in action; the erratic measurements in the top graph are "toned down" to become the measurements in the bottom graph.

When an acceleration passes the threshold, I also get the current heading from the compass. The heading is returned in the form of a float from 0-360 degrees, where 0 is North, 90 is East, etc. These directions are usually based on true North, but if that data is not available then magnetic North is used. Heading is measured with respect to the top of the phone, so some trigonometry may be required in the future if the phone is tilted.

Once the heading measurement is recorded, I used the TouchJSON library to encode the three accelerations and heading as a JSON string. Using the ASIHTTPRequest library, I sent the JSON to a Node.js backend (currently running on my laptop), where the heading value is converted to a string value like "N", "NW", "NNW", etc. For next week I hope to replace the Node backend with Unity/C#. In the long term, I also hope to develop more rigorous ways of detecting a gesture in addition to the threshold and filters. I will be reading up on the iOS shake gesture recognition code.

3 comments:

  1. How does the iPhone know the difference between magnetic and true North? Typically the declination between the two would have to be dialed in for that kind of conversion, but it would take a GPS to be aware of that as it changes depending on geographical location.

    If you already have a .js (javascript) for your Node, it may be faster to attach Unity's hooks in javascript and hold off on jumping languages until after the Oct. 20th deadline if javascript won't interfere with the rest of what you need to do. Unity handles javascript fine.

    ReplyDelete
  2. The iPhone uses its GPS to determine true North. These calculations are done automatically by the CoreLocation framework. If the GPS/Location Services are not available, then it falls back on magnetic North. To use this application the user must enable Location Services (option is given when the app is first installed), so we can assume that all directions are true rather than magnetic.

    I will look into handling the Javascript in Unity today. Thanks!

    ReplyDelete
  3. Hmm, if it has an exposed GPS we may consider switching to that from the compass at some point.

    ReplyDelete