Computer science, meet exercise: How I built a push-up pedometer at a three day hackathon
One of my favorite features of my phone is that it automatically measures my steps without me ever having to open an app. Recently though, I’ve been wanting a metric for measuring upper body activity and performance that can be automatically counted like pedometers can for steps. I use a lot of bodyweight exercises in my workouts and realized an automatic counter for push-ups and pull-ups would be extremely helpful for tracking my progress. Thus went the ideation for “Swole”, a pedometer for pushups. This weekend I had the incredible opportunity to try and create this concept at a 3 day hackathon called Wearhacks LA with a team from the USC Iovine & Young Academy.
Day One, 9:00pm—Midnight
Hackathons, for the uninitiated, are events where people meet up to compete to program and build a solution to some problem, usually in a very limited amount of time. Often unhealthy amounts of junk food and little to no sleep are involved. As soon as the hackathon started, I rented out the hardware we would need. For measuring arm motion, I opted to get a Myo armband from the hardware lab. The Myo is a motion tracker worn on the upper forearm that can connect to any bluetooth enabled phone or computer. It contains an IMU and 8 EMG sensors which allow it to detect the position of your arm and the articulation of your fingers.
I decided to limit our team’s app to counting only push-ups and use the Myo linked to a computer. I didn’t want to waste time writing an app for a mobile device or multiple algorithms that would only take more time to test. The Myo development site had a sample C++ program that dumped all the data (accelerometer, gyroscope, EMG) from a Myo-wearing person into spreadsheets. I put the Myo on, and did a few pushups while running the data collection program and graphed the results in Excel. I was surprised to see how identifiable a pattern was in the x axis among the noisy data. A quick Google search turned up two simple methods of smoothing data: exponential smoothing and moving average smoothing. I created formulas for both in Excel and applied them to the data in various configurations until my data looked smooth to my eye on the graph. The final smoothing algorithm included 4 passes of the exponential smoothing function with an alpha of .45 and moving average of the previous 4 points. I also ran tests on other team member’s pushup motion data to account for variation in technique.
Day Two, 9:00am—Midnight
Now that I had a good dataset to work with, how would I actually detect a pushup? I’d never written anything like this before, but I knew of one place where similar algorithms are used all the time: Handwriting detection on tablets. Basically, instead of trying to analyze the bitmap of some line after it’s been drawn, it’s easier to recognize patterns if the line is represented as a series of vectors illustrating the direction of the stroke over time. In order to make my 3 dimensional data work with a 2 dimensional gesture recognizer I combined the y-axis and z-axis data into one set of magnitudes — we’ll call it the w-axis for short — using the Pythagorean theorem. Now my I could use my original x-axis and w-axis data to simulate drawing lines on a screen for a gesture recognizer.
At this point I had to go back and start actually writing my application. I decided to use Java because it was the language I remembered most off the top of my head. I wrote a few lines to import the CSV file into some arrays, and then rewrote my Excel functions in Java to smooth the data there. Finally I added a method that transformed my point data into vector strings and output that to the console. I ran this Java program with my pushup data and put the resulting string of vectors into my Excel spreadsheet alongside the raw data. To my surprise, when I looked at the time periods where I knew a pushup occurred, I saw this sequence of vectors: “S — W — NW — NW — NW — N — N — N”. I checked my teammate’s data as well and saw similar sequences. I put all the sequences of vectors for each pushup side by side and color coded the vectors. There definitely was a pattern there. [Insert screenshot] I created a sequence of vector strings that I thought matched the data best, and decided to test it as our model.
Back in the Java program, I implemented a fuzzy string matching function that I found on Google Code. This allowed me to search the entire sequence of vectors for the specific sequence I had defined as the “perfect pushup model” and return the location of it. The fuzzy string matching also allowed me to tune how accurate the matches had to be and there approximate location (so I didn’t get duplicates). I tuned the function to my original data sets so it recognized the correct amount of pushups, and then it was time to test it. I put on the Myo and knocked out 50 quick push-ups. My Java program counted 43. In the interest of time, I decided the model worked well enough (the average accuracy was about 83%). This was at the end of the second day, so I would only have a few hours in the morning to help my teammates finish the web app that displayed the data.
Day Three, 9:00am—1:30pm
While I was designing the algorithm for counting pushups, my teammates were working on a website that would display useful metrics gleaned from the data, such as the current tally for the day, previous week’s and month’s tallies, averages, etc. We decided to use Parse for our backend, so the next morning I added a small bit of code to upload the count to our database after the data collection was done. The only thing I had left to do to create a smooth demo was automate running the Myo data collection program and my Java program that analyzed those results. Using Automator, I set up a folder action that would run a script every time a file was added to it. The script would run the Java program with the file name as an argument, and then delete the file after it had finished running. All I had to do now was run the data-collection program in that directory and the number of pushups would automatically be counted and sent to our Parse database, where our website could access the information.
We ended up winning the prize for best design, but the Swole app isn’t stopping there. I’ve uploaded the code we used to GitHub for anyone to download and try running. Right now, our demo only counts pushups, but we could add other exercises using a combination of motion data from smartwatches and phones. The algorithm has a lot of room for improvement, and once the project is transitioned from the Myo to another, more readily available platform such as Apple Watch, I think I’ll be working on making it more accurate. I also want to create a new version of the web interface that supports data from other fitness tracking platforms so I would be able to see all my data side by side. Eventually this website would be able to analyze your data and recommend workouts to help you meet your fitness goals.
Overall, Wearhacks LA was an amazing experience, and I had so much fun creating this application. Shout-out to my teammates Jane, Jared, Joseph, and Sara for being such great sports and helping pull this hack off, thank you. If you’re at all interested in becoming a better programmer, or just want to make something cool, find a local hackathon and do it! You’ll be surprised at what you’re capable of creating when you push on the limits of your creativity.