Whee! Accelerometer!

Whee! Accelerometer!

Chapt ~, Whee! ~t- u a- Accelerometer! of the coolest features of the iPhone and iPod Touch is the built-in acceler- 1I.1•~• ~meter, the tiny device that lets the iPhone know how it's being held and if it's ~J~ being moved. The iPhone as uses the accelerometer to handle autorotation, and many games use it as a control mechanism. It can also be used to detect shakes and other sudden movement. n Accelerometer Physics An accelerometer measures both acceleration and gravity by sensing the amount of inertial force in a given direction. The accelerometer inside iPhone is a three-axis accelerometer, meaning that it is capable of detecting either movement or the pull of gravity in three-dimensional space. As a result, you can use the accelerometer to tell not only how the phone is currently being held (as autorotation does) but also if it's laying on a table and even whether it's face down or face up. Accelerometers give measurements in g-forces ("g"for gravity), so a value of ~.. 1.0 returned by the accelerometer means that 1 g is sensed in a particular direction. If the iPhone is being held still with no movement, there will be approximately 1 g of force exerted on it by the pull of the earth. If the iPhone is being held perfectly upright, in portrait orientation, the iPhone will detect and report about 1 g of force exerted on its y axis. If the iPhone is being held at an angle, that 1 g of force will be distributed along different axes depending on how the iPhone is being held. When held at a 45-degree angle, that 1 g of force will be split roughly equally between two of the axes. Sudden movement can be detected by looking for accelerometer values considerably larger than 1 g. In normal usage, the accelerometer does not detect significantly more than 1 g on any axis. If you shake, drop, or throw your iPhone, the accelerometer will detect a greater amount of force on one or more axes. Please do not drop or throw your own iPhone to test this theory. You can see a graphic representation of the three axes used by iPhone's accelerometer in Figure 15-1. One thing to notice is that the accelerometer uses the more standard conven- tion for the y coordinate, with increases in y indicating upward force, which is the opposite of Quartz 20's coordinate system. When you are using the accelerometer as a control mecha- nism with Quartz 20, you have to translate the y coordinate. When working with OpenGL ES, which you are more likely to be using if you are using the accelerometer to control anima- tion, no translation is required. -x +X +z -z -y Figure 15-1. The iPhone accelerometer's axes in three dimensions Accessing the Accelerometer The UIAcce 1e romete r class exists as a singleton. To retrieve a reference to the class, call the method sharedAccel erometer, like so: UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer]; Getting information from the accelerometer is similar to getting information from Core Location. You create a class that conforms to the UIAccel erometerDel egate protocol, implement a method to which the accelerometer will provide information, and specify an instance of that class to be the accelerometer's delegate. When you assign a delegate, you need to specify an update interval in seconds. iPhone's accelerometer supports polling at a rate of up to 100 times per second, although there is no guarantee that it will actually update you that many times or that those updates will be exactly evenly spaced. To assign a delegate and specify a polling interval of 60 times per sec- ond, you would do this: accelerometer.delegate = self; accelerometer.updatelnterval = 1.0f/60.0f; Once you've done that, all that's left is to implement the method that the accelerometer uses to update its delegate, acce 1e romete r: di dAcce 1e rate:. This method takes two argu- ments. The first is a reference to the shared UIAcce 1e romete r instance. The second contains the actual data from the accelerometer, embedded in an object of the class UIAcce 1e rat; on. Before we look at the delegate method, let's talk about the UIAccel er-at i on object that's used to pass the information to the delegate. UIAcceleration We mentioned earlier that the iPhone's acceler- ometer detects acceleration along three axes, and it provides this information to the delegate using instances ofthe UIAcce 1e rat; on class. x:o.o y:-l.0 z:O.O Each UIAcce 1e rat; on instance has an x, y, and z property, each of which holds a signed float- ing point value. A value of 0 means that the X:l.0 y:O.O z:o.O accelerometer detects no movement on that particular axis. A positive or negative value indicates force in one direction. For example, a negative value for y indicates that downward pull is sensed, which is probably an indication x:O.O y:l.0 z:o.O that the phone is being held upright in portrait orientation. A positive value for y indicates some force is being exerted in the opposite :~\, x:-l.0 y:O.O z:o.O direction, which could mean the phone is IL!'!'!"!]L) being held upside down or that the phone is being moved in an upward direction. 4iiiil•• liEWIi·· Ii·. x:o.O y.o.o z:-1.0 Keeping the diagram in Figure 15-1 in mind, let's look at some accelerometer results. Note x:O.O y:O.O z:1.0 that, in real life, you will almost never get values this precise, as the accelerometer is Figure 15-2. Idealized acceleration values for sensitive enough to pick up even tiny amounts different device orientations . of motion, and you will usually pick up at least some tiny amount of force on all three axes. This is real-world physics and not high school physics lab. Implementing the accelerometer:didAccelerate: Method In order to receive accelerometer information, the class you specify as the accelerometer's delegate needs to implement the accel erometer: di dAccel erate: method. Ifyou wanted to display the acceleration values in a UILabel, you might implement that method like this: - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { NSStri ng =newf'ext = [[NSStri ng alloc] initWithFormat:@"x: %g\ty:%g\tz:%g", acceleration.x, acceleration.y, acceleration.z]; label .text = newText; [newText release]; } This method would update a label on the interface every time it was called. How frequently this method gets called is based on the updatelnterva 1 value you specified earlier. Detecting Shakes One fairly common use of the accelerometer in applications is to detect a shake. Like a ges- ture, a shake can be used as a form of input to your application. For example, the drawing program GLPaint, which is one of the iPhone sample code projects, lets the user erase draw- ings by shaking the iPhone, sort of like an Etch-a-Sketch. Detecting shakes is relatively trivial; all it requires is checking for an absolute value on one of the axes that is greater than a set threshold. During normal usage, it's not uncommon for one of the three axes to register values up to around 1.3 gs, but much higher than that generally requires intentional force. The accelerometer seems to be unable to register values higher than around 2.3 gs (at least on first-generation iPhones), so you don't want to set your threshold any higher than that. To detect a shake, you could check for an absolute value greater than 1.5 for a slight shake and 2.0 for a strong shake, like this: - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { if (fabsf(acceleration.x) > 2.0 II fabsf(acceleration.y) > 2.0 II fabsf(acceleration.z) > 2.0) { II Do something here ... } } he preceding method would detect any movement on any axis that exceeded two g-forces. You could implement more sophisticated shake detection byrequiring the user to shake back and forth a certain number of times to register as a shake, like so: (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { static NSlnteger shakeCount o·, static NSDate *shakeStart; NSDate *now = [[NSDate alloc] init]; NSDate *checkDate = [[NSDate alloc] initWithTimelnterval:l.5f sinceDate:shakeStart]; if ([now compare:checkDate] == i NSOrderedDescending II shakeStart nil) { shakeCount = 0; I [shakeStart release]; shakeStart = [[NSDate alloc] init]; } I [now release]; I [checkDate release]; I if (fabsf(acceleration.x) > 2.0 II fabsf(acceleration.y) > 2.0 I II fabsf(2.0.z) > 2.0) { ! shakeCount++; I if (shakeCount > 4) { I II Do something I shakeCount = 0; I [shakeStart release]; ! shakeStart = [[NSDate alloc] init]; } } } This method keeps track of the number of times the accelerometer reports a value above 2.0,and if it happens four times within a second and a half span of time, it registers as a shake. Accelerometer as Directional Controller Probably the most common usage of the accelerometer in third-party applications is as a controller for games. Instead of using buttons to control the movement of a character or object in a game, the accelerometer is used. In a car racing game, for example, twisting the iPhone like a steering wheel might steer your car, while tipping it forward might accelerate and tipping back might brake. Exactly how you use the accelerometer as a controller is going to vary greatly depending on the specific mechanics of the game.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    22 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us