Shannon Appelcline

Subscribe to Shannon Appelcline: eMailAlertsEmail Alerts
Get Shannon Appelcline: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn


Related Topics: iPhone Developer

iPhone Developer: Article

Book Excerpt: iPhone in Action

Using the iPhone's accelerometers

You filter things, as noted, by averaging 10% of the active movement together with 90% of the average (#1). This smooths out any bumps, which practically means that sudden acceleration will be largely ignored. You did this for the x and y axes because that's all we were using in the example. Clearly, if you cared about the z-axis, you'd need to filter that too.

Afterward use the averaged acceleration instead of the raw acceleration when changing the position of ball (#2). From what looked like an imposing mass of data, you managed to extract the gravity information with just a couple of lines of code.

As we'll see, looking at only the movement is just as easy.

Checking for Movement
In our previous example, we isolated the gravitic portion of the accelerometer's data by creating a simple low-pass filter. With that data in hand, it's trivial to create a high-pass filter. All you need to do is subtract out the low-pass filtered data from the acceleration value; the result is the pure movement data. This process is shown in Listing 5.

We should first offer the warning that this filter does not entirely stop gravitic movement. That's because it takes several iterations for the program to cut out gravity completely. In the meantime, your program will be influenced by gravity for a few fractions of a second at startup and afterward. If that's a problem, you could tell your program to ignore acceleration input for a second after loadup and after an orientation change. We'll show the first solution in our next example.

Absent that caveat, as soon as you start using these new variables, you'll be looking at the filtered movement information rather than the filtered gravity information. However, when you start looking at movement information, you'll see it's a bit trickier to use than gravity. There are two reasons for this.

First, movement information is a lot more ephemeral. It will appear for a second and then be gone again. If you're doing some type of continuous movement, as with the red ball example, you'd need to make your program much more sensitive to detect the movements. You'd have to multiply your moveX and moveY by about 25x to see movement forces applied therein.

Second, it's a lot noisier. As we'll see when we look at some real movement data, it occurs in a multitude of directions at the same time, forcing you to parse out the exact information that you want.

Ultimately, to interpret movement you have to be more sophisticated, recognizing what are effectively gestures in 3D space.

Recognizing Simple Accelerometer Movement
If you want to write programs using acceleration gestures, download the Accelerometer Graph program available from Apple's developer site. This is a nice, simple example of accelerometer use, but more important it also provides you with a clear graph of what the accelerometers report as you make different gestures. Make sure you enable the high-pass filter to get the clearest results.

Figure 2 shows what the Accelerometer Graph looks like in use (but without movement occurring). As you move around an iPhone, you'll quickly come to see how the accelerometers respond.

Here are some important facts about how the accelerometers report information when you look at the Accelerometer Graph:

  • Most gestures will cause all three accelerometers to report force; however, the largest force should usually be in the axis of main movement.
  • Similarly, even though there's a compensating stop force, the start force will typically be larger, and thus show the direction of main movement.
  • Casual movement usually results in forces of .1g to .5g
  • Slightly forceful movement usually tops out at 1g
  • A shake or other more forceful action will usually result in a 2g force
  • The accelerometers can show things other than simple movement. For example, when you're walking with an iPhone, you can see the rhythm of your pace in the accelerometers.

All of this suggests a simple methodology to detect basic accelerometer movement: you monitor the accelerometer over the course of movement, saving the largest acceleration in each direction. When the movement has ended, you can report out the largest acceleration as the direction of movement.

Listing 6 puts these lessons together by creating a program that could easily be used to report the direction of the iPhone's movement (which you can then use to take an arbitrary action).

As usual, start by creating a low-pass filter (#1), then taking the converse of it (#2) in order to get relatively clean movement data. Because the data can be a little dirty at start, don't accept any data until a second has passed after the first acceleration data was sent (#3). You could cut this down to a mere fraction of a second.

Start looking for movement whenever one of the accelerometers goes above .3g (#4). When that occurs, save the direction of highest movement (#5) and keep measuring it until all of the .3g+ movement has occurred. Afterward make sure that at least a tenth of a second has passed (#6), so that you know you're not just in a lull during a movement.

Finally, do whatever you want to do with your movement data. Here, just report out the information in a label (#7), but you'd doubtless do something much more intricate in a live program. Cleanup is required (#8) to get the next iteration of movement reporting going.

Generally this sample program does the right thing except if movement is very subtle. In those cases it occasionally goes the opposite direction due to the force that's reported when the device stops its motion. If this type of subtlety is a problem for your application, more work would be required. To resolve this, you'd need to make a better comparison of the start and stop forces for movements; if they're similar in magnitude you'll usually want to grab the first force measured, not necessarily the biggest one. However, for the majority of cases, what you've programmed is sufficient, and you now have an iPhone application that can accurately report (and take action based on) direction of movement.

More Stories By Christopher Allen

Christopher Allen is one of the leaders of the iPhone developer community. He is the host of iPhoneWebDev.com, which is the largest independent community of iPhone-based web developers, and manages its mailing list. He is also one of the founders of iPhoneDevCamp and oversees its Hackathon, and is co-author of iPhone in Action:Introduction to Web and SDK Development. Christopher is a longtime technologist, and is also a leader in social software and was one of the authors of TLS, the next-generation SSL protocol.

More Stories By Shannon Appelcline

Shannon Appelcline is a writer and technologist. He was a participant in Charles River Media's Massively Multiplayer Game Development 2. He has also been published by Chaosium Inc., Issaries Inc., Jones Publishing, Partizan Press, White Wolf Publishing, and Wizards of the Coast. In 2007 he wrote over 350,000 words for professional publication, including books for Mongoose Publishing and Moon Design Publications. He has also written fiction published by Green Knight Publishing and comic books published by Skotos Tech.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.