Detecting a Golf Swing From a Phone in Your Pocket: Why I Settled for the Tee Shot

Posted on October 30, 2026

Category: Technology

Tags: android, flutter, dart, sensors, gyroscope, accelerometer, signal-processing, golf, gps, motion-detection, field-testing

Views: 14

Detecting a Golf Swing From a Phone in Your Pocket: Why I Settled for the Tee Shot

GPS4Golf, my Android golf GPS app, measures drive distance with two taps. You tap Mark where you hit from, walk to the ball, and tap Mark again. The app measures the distance between the two points.

The weak point is the human. On a busy tee, with a playing partner talking and a glove to put back on, the first tap is the one that gets forgotten. Without it there is no drive distance for that hole, and a drive is the number the app exists to record.

The phone has a gyroscope and an accelerometer, and it is in my pocket for the whole round. So the obvious idea was to let the phone notice the swing and Mark it automatically. This post is about why that idea did not survive real rounds, and about the much narrower feature that did.


The setup

The phone lives in my right front pocket for the whole round. I am right-handed, so that is the trail leg, which turns hard toward the target in the downswing. Detection runs on rotation magnitude, so it does not matter which way up the phone sits in the pocket.

The first version logged only. Whenever the gyroscope saw a fast rotation, the app wrote a swing row to the round's event log with the peak rotation, the peak acceleration and how long the signal stayed above the trigger. Nothing was marked automatically. The plan was to play rounds, compare the rows with my manual Marks, and only then decide on a rule.


Round one: walking looks like swinging

The first log was mostly walking. While I walked, a row appeared roughly every 3 seconds, with peak rotation between 5 and 8 rad/s and less than 100 ms above the trigger. Real tee swings peaked between 10 and 17 rad/s and stayed above the trigger for 250 to 450 ms.

That looked like a clean split until the walking rows were removed. Then the remaining rows near real shots and the rows everywhere else had almost the same distributions. The reason was practice swings. I take one or two between shots, and from the pocket a practice swing and a real one produce the same rotation, for the same duration.

One tee made it plain. On the 17th I hit five tee shots, and the roughly 20 rows logged while I stood there all sat between 5 and 9.2 rad/s. Nothing in them said which five had hit a ball.

A rule based on position worked better than one based on motion. A spot where I stayed within 12 m for 30 seconds and then moved more than 50 m within 90 seconds reproduced all 27 of my manual Marks. It also produced 99 candidates for a round of about 46 full shots, so it could not be trusted to add strokes on its own.


Round two: the ball leaves a mark

Rotation cannot separate a practice swing from a real one, but one thing does differ: a real swing hits a ball. Impact should show up as a short jolt in the accelerometer right at the bottom of the swing, where the rotation peaks.

So the app started recording raw waveforms from both sensors whenever a fast rotation happened while GPS said I was standing still. From each waveform it computes one number, the spike: how far the acceleration jumps above its local baseline in a short window around the rotation peak. Comparing against the local baseline cancels out the slow, large acceleration of the leg turning, and leaves the sharp jolt of the strike.

With a cut-off of 15, this was the first measurement that separated practice from play. Across two rounds no practice swing reached 15. The cost was recall:

Real shots with a spike of 15 or more:

From a pocket, half of all drives and almost no other shots produced a jolt that big. That rules out automatic Marks for every shot. A feature that catches one fairway shot in five is worse than none, because the user stops trusting the Marks it did make.


The narrower feature

The useful part of those numbers is the first line. On a driver tee, a spike almost always means a real shot, and a driver tee is exactly where the forgotten Mark costs the most. The app already had a check for that case: when the first Mark of a hole is far from the course's tee, it asks whether to add the tee shot. Swing detection now makes that check better instead of replacing it:

  1. On a par 4 or 5 with no Mark yet, a standing swing with a large enough spike near the course tee is remembered as where the tee shot was hit. Mulligans and practice swings simply overwrite it; they happened on the same tee box anyway.
  2. Nothing happens on screen at that point. If I remember to Mark the tee, the remembered spot is never used.
  3. If my first Mark of the hole is far from the tee, the app inserts the tee shot at the remembered spot without asking, and shows an Undo.
  4. If no swing was detected, the app falls back to the old question and offers to add the tee shot at the course's tee.

The detected spot is better than the course data, because it is the tee box I actually played from rather than the one OpenStreetMap recorded. In the first round with this logic, the one automatic insertion landed 0.4 m from where the swing had been detected.


Then the threshold stopped working

The next round inserted nothing. Every forgotten tee Mark fell back to the question.

The log explained it. That day's tee shots had spikes between 10 and 14. None reached 15. The cut-off had been chosen from the two rounds where it worked, and it did not hold up on a third day. A different pair of trousers, the phone sitting differently in the pocket or a slightly different strike could each account for a few units.

The fix was to stop treating 15 as meaningful. The cut-off is now far lower, just high enough to filter out footsteps. Lowering it so far is safe because of where it applies: a false positive at that point is a practice swing on the same tee box, so the inserted tee shot is still in the right place, give or take a few metres, and Undo is right there. The strict threshold was protecting against a mistake that costs almost nothing.


Holes with no tee in the map

Some courses in OpenStreetMap have greens but no tees, so "near the course tee" has nothing to measure against. For those holes, a standing swing counts as a tee shot when it is far enough from the green for the hole's par, a longer distance on a par 5 than on a par 4.

That rule has a hole of its own. A short drive on a long par 5 can leave the second shot still far enough from the green to pass, so the second swing would replace the tee spot. Once a spot has been detected, later swings can replace it only if they are within roughly a tee box of it. Mulligans still overwrite it, while the second shot down the fairway cannot.


What I would tell myself at the start

The first post in this series covered how the course data is built, in From OpenStreetMap to a Golf Course API. The app itself is GPS4Golf, available on Google Play.


References


Disclaimer: This blog post was created with assistance from Claude, an AI developed by Anthropic, under my direct supervision and guidance to ensure accuracy and alignment with my vision for the content.