Improving Auto-Pause for Everyone

Strava Engineering
strava-engineering
Published in
9 min readDec 16, 2014

Every time an athlete uploads an activity to Strava, the server analyzes the activity and calculates various metrics for it. For each activity, the server calculates “elapsed time” (the time between the athlete starting the recording and ending it), and “moving time” (a measure of how long the athlete was actually moving). Moving time is then used to calculate additional statistics such as splits and pace data for runs.

About a year ago, when the iPhone 5s was released, we used the new phone’s automatic activity type detection to create an auto-pause for runners. This allowed them to see moving time before they uploaded, while they were still running. Ever since then, we wanted to make auto-pause available to everyone, including runners with phones other than the iPhone 5s, and cyclists (the iPhone 5s detected when a user was running or walking, but not cycling). Our goal was to create a consistent experience across all devices while being as accurate as possible in calculating the metrics our athletes care about.

This post describes how we developed our new auto-pause feature for runners and cyclists.

Auto-pause for Cyclists

Cyclists often carry their phones in their jersey pockets and are not typically concerned with pausing the timer every time they stop for just a few seconds. Their most important concern is that the app does not miss any part of their route, while still showing an accurate moving time at the end of the activity. For this reason, we built the cycling auto-pause to be as inclusive as possible.

We started by looking at the process we have on our server for calculating moving time after upload and figuring out how to make that happen in real-time. The moving time calculation on the server looks for portions of the activity where the athlete was moving below a certain speed threshold for more than 15 seconds and removes that time as “resting time”, leaving the remainder as moving time.

On the phone, we built auto-pause to detect a pause by seeing if the athlete has been stationary for more than 10 seconds. The usual way for an app to access the phone’s location is for the OS to determine the location of the phone and send out updates at regular intervals to any apps that want the location information. The catch is that iOS and Android only send these updates reliably when the phone is moving, which makes it difficult to determine when the phone is stationary. So we detect whether the phone is moving by looking at whether we have received a location update with a positive speed in the last 10 seconds. If we have gone more than 10 seconds without a location update, we auto-pause the app.

Another interesting aspect is that because the server looks at the activity as a whole, when it sees that an athlete was stopped for, say, 25 seconds, it will remove the entire 25 second block as resting time. But because auto-pause on the phone operates in real-time, it can only pause after 10 seconds. In this case, we do not “roll back” time, and only the 15 seconds of stopped time after the pause will be removed as resting time.

When the app is auto-paused, it will resume as soon as the phone reports a location that 1) is a certain minimum distance away from the location where it paused and 2) indicates that the athlete is moving faster than a certain minimum speed.

The result of all this is an auto-pause that detects longer stops, like waiting for a minute or more at the top of a climb, but not necessarily very short stops, like just a few seconds at a stop light. Given how long rides typically are, a difference of a few seconds does not usually make a material difference in the overall moving time for an activity. More important is reliability, and the app pauses slowly and resumes quickly, so it is very unlikely to pause while an athlete is still moving, and it should resume almost immediately when she starts moving from a stop.

Finally, the straight-line distance between the last moving point before pausing and the first moving point after resuming is included in the activity. This means that if an athlete bikes through a tunnel, the app will pause while the athlete is in the tunnel (because it is not receiving any location updates during that time), but once the athlete emerges, the distance that the athlete biked through the tunnel will be included in the activity. Also, if the GPS wanders around a little while the athlete is stationary, the activity will not include that wandering distance, just the straight-line distance between the last moving point before pausing and the first moving point after resuming.

Auto-pause for Runners

Runners typically care a lot about how responsive auto-pause is. Some runners will stop and start their watches manually at every stop sign to make sure the time recorded by the watch represents the time they are actually running as accurately as possible. This is mostly important for knowing things like splits and average pace during a run, and compared to rides, a few seconds here and there makes a meaningful difference so it is important to catch every little stop accurately.

As an example, imagine an athlete who runs 1 mile and stops 3 times during the mile for 20 seconds each time, reaching the end of the mile after 8 minutes. With no auto-pause and no manual pausing, her phone will count all of that stopped time as running time and tell her she is running at an 8-minute pace, when really she is running at a 7-minute pace.

The naive pace calculation can be summarized as:

7:00 running + (3 x 0:20 stopped) = 8:00 per mile

Our goal for run auto-pause was to show runners a real-time average pace number as close to that 7-minute pace as possible.[1]

To bring this functionality to all of our athletes beyond just those with iPhone 5s, we first tried building run auto-pause based on GPS location updates similar to the way we had built ride auto-pause. Unfortunately, it was not responsive enough — resuming was fairly quick and usually happened within a couple of seconds of the athlete starting to run, but pausing sometimes took 5 seconds or more of standing still. For our 7-minute miler described above, this would mean the phone would show her a pace of around 7:15–7:25 minutes per mile, which was not good enough to be a useful replacement for stopping a watch manually.

GPS auto-pause (average case):

7:00 running + (3 x 0:07 stopped) = 7:21 per mile

We experimented with making it more sensitive to minor GPS movement, but that caused errors — it would sometime pause while running or resume while standing still.

Instead of GPS, we decided to look at the accelerometer data. The accelerometer provides near-instantaneous values for acceleration, so we thought we would be able to get very fast response times by detecting the motion of running, i.e. the type and intensity of periodic shaking that indicates the athlete is running.[2]

We tried processing the accelerometer signal various ways to detect running motion, and ultimately developed an algorithm based on changes in the time-averaged jerk (jerk is the derivative of acceleration, sort of a measure of how sharply the phone is being shaken). A certain increase indicates the athlete has started running, and a corresponding decrease indicates she has stopped running.

After a few rounds of in-house testing, we managed to tweak the algorithm so that it would work for most of our athletes. We are able to pause and resume the app within about a second of when a runner would pause and resume her watch if she were doing it manually. This means that in most cases, the time recorded by the app will be correct to within 5–10 seconds per mile even if an athlete stops 2–3 times per mile.

Accelerometer auto-pause (average case):

7:00 running + (3 x 0:02 stopped) = 7:06 per mile

This is a big improvement over our attempts at GPS auto-pause and within the standard we set out to achieve.

Because the algorithm detects the motion of running and does not require the GPS to indicate movement, if an athlete runs in place at a stop light, the app will not pause. It also will not pause if the athlete loses GPS but keeps running, e.g. in a tunnel.

Another difference between the new auto-pause and our attempt at auto-pause based on GPS is the new auto-pause will only resume when the athlete is running, not walking. The jerk calculation can detect quite quickly when an athlete starts and stops running, but it would be slow to detect the subtle motion of walking. Also, in our user testing, we discovered that runners who care most about the responsiveness of auto-pause generally do not count their walking time.

One downside of the accelerometer approach is that if the athlete holds the phone very steady in her hand while she is running — in order to read the screen, for example — this can smooth the motion enough to trigger a pause. To correct this, we built a back-up resume function that will resume the app again within a few seconds based on GPS data as long as the athlete is still running.

Because our new method is a better approximation of the true time an athlete is running, the server now skips all post-processing when an athlete records with auto-pause. This means that the stats the athlete sees in the app at the end of the activity — including overall time, splits, and pace — will be the same stats that appear on Strava after uploading. If an athlete wants to include walking, or prefers to rely on server-side post-processing to determine moving time for an activity, she can turn auto-pause off and we will continue to remove resting time the way we have in the past.

We have learned a lot implementing auto-pause: we know more about how runners and cyclists think about data differently, we know about the relative advantages of processing data in real-time vs post-upload, and much more. We are really pleased with the way this feature came out and think it is a big win for our athletes. At the same time, it has given us a lot of ideas about other ways we can serve our athletes better in the future, particularly in the realm of data accuracy.

Footnotes

[1] This discussion focuses on how we are using auto-pause to improve the accuracy of the time input to the time / distance = pace equation. For the sake of clarity, it assumes there is no error in the distance input. Unfortunately, distance measured by the phone is not perfect due to accuracy limitations in location measurement — GPS error usually causes distance to be a little long, resulting in a pace number that is a little fast.

This is why, even though auto-pause introduces error of no more than a few seconds per mile, pace shown by the phone during a run could be off by more than this amount due to this GPS error. Luckily the errors go in opposite directions — extra time from stopping causes pace to be slower than it should be, while extra distance from inaccurate GPS causes pace to be faster than it should be — so they cancel each other out to some extent.

[2] We also looked at the accelerometer data to see if it would show when an athlete was cycling vs. stationary, but separating noise from signal in that case turned out to be quite difficult and we decided it was beyond the scope of what we wanted to accomplish in this first phase of our auto-pause implementation.

Originally published at labs.strava.com by Jay Harris.

--

--