It is not too uncommon to find that the hardware you are given for a project does not meet your expectations and limits the design possibilities. Still you are required finish the job and produce a product that is acceptable for the customers. The limitations can come from insufficient processing power, memory constraints, lack of GPIO, bandwidth limitations, inaccurate sensors, and many other factors.
This article talks about a quite specific issue that I encountered when developing my very first iPhone application. I’ve been using accelerometers at work for various purposes, and am quite familiar with their strengths and limitations so I figured I would do something fun with the accelerometer in the iPhone. I didn’t want to spend a whole lot of time developing the application, but I wanted to create something that was pleasant and fun for the users. So I did a little bit of research and found that no one had done an application that measures the speed of a throw, in particular that of a baseball pitcher. This turned out to be untrue, but I understand now why there aren’t any best selling iPhone apps measuring throwing motions.
Measuring speed… …or not
At first it sounds like a pretty simple deal, calculating the velocity of a fictitious ball thrown by the user. Just measure the acceleration of the iPhone device and integrate, then show the maximum speed to the user. Of course there is the problem that accelerometer readings include the gravitational force, but I thought that could easily be filtered out using a high pass filter, or better yet, combine the accelerometer readings with readings from the gyro available in the iPhone 4.
What I forgot to think about, is that the accelerometer only measures acceleration forces up to three times the gravitational force. A throwing motion generates forces up to 10 times as much, so any acceleration readings would cap at 3G, and wouldn’t be of much use for integrating to get speed.
Another thing I didn’t know about the iPhone, is that it is not easy for an application to do high resolution samples from the accelerometer, or any other sensor for that matter. It turns out that although the API’s support high resolution timers, the operating system doesn’t give your application unlimited access to the Processor. The operating system actually locks out the application for quite significant amounts of time, at least in the context of high frequency sampling. So although it theoretically would be easy to just poll the timer, and read accelerometer samples say every millisecond, it turned out to not work that well.
So after a couple of depressing findings I was thinking if this was the end of my simple idea application. Since I had done all the graphics and coded the controls, I didn’t want to let that all go to waste. So I came up with something that could be done to at least approximately measure the speed.
After doing some tests and plotting the graphs of different accelerometer readings, I found that it was fairly easy to detect the duration of the throwing motion. The acceleration during the throwing motion was always greater than 3G so by checking the start and end time of when the accelerometer readings cap at 3G, I got a pretty good estimate of the duration of the throw.
Then I estimated the length of the throwing motion to be around 0.5 meter. Then it is straight forward to estimate the acceleration using the equation s = v0t + at2/2. Some compensation for the actual twisting motion of the wrist had to be added, as well as for the fact that the acceleration is not linear. Calculating the speed using the approximated acceleration is then trivial.
Another thing I was hoping to include in the motion calculation was the amount of spin the user adds to the ball. The iPhone is obviously not a baseball, so techniques to add spin could not entirely mimic a real world scenario. But at least I was hoping to simulate it by calculating the rotational speed and then estimate the spin of the ball.
This turned off course also out to be a hopeless task with the limitations of the accelerometer. So to work around the issues I set up a simple model, where the program checks the acceleration vector when the device is at rest just prior to the throwing motion as well as just after. By calculating the angle between the vectors, it is possible to make an approximation of how the hand was turned during the throw. This is obviously even less accurate than the speed approximation, but testing showed that it was more accurate than I first thought.
Based on the change in angle, it is possible to estimate if the user put e.g. a top spin, clockwise or counter-clockwise spin in the throw. This can roughly be correlated to the different types of pitches in baseball, and even left and right handed pitching can be simulated.
Although the result is not as great as I was hoping for before I started the project, it turned out to not be too bad either. The biggest issue is that the approximations require the user to follow the models when performing the throwing motion. And if the user don't move the iPhone according to the model, the results may be quite arbitrary. The problem getting good high frequency samples are also affecting the result, and sometimes the output is not accurately reflecting the throw.
Regardless of whether you like the end result or not, It was a pretty exciting challenge to get something reasonably accurate considering the pretty tough constraints of the iPhone accelerometer.