Hi all,

This was the week the "AI" in this whole series was meant to stop being a tagline and become real code. It did — but not in the clean, triumphant way I'd pictured. What actually happened is more useful, and I'd rather tell you the true version than the flattering one.

Short version: I built a machine-learning model that accurately predicts how long a satellite will stay usable overhead. Then I tried the obvious thing — using that prediction to pick satellites — and it made hand-offs worse, not better. Working out why, and fixing it, is what this week was really about.

Some background. Week 3's scheduler picked satellites with a simple rule: whichever visible satellite has the best link margin right now wins. It works, but it's short-sighted — the best satellite right now might be seconds from dropping below the horizon, forcing an immediate hand-off. So the plan for Week 4 was to look ahead: if I could predict how long each satellite would stay usable, I could pick the one giving the best sustained link, and (I assumed) cut down on hand-offs.

The model itself is honest and it works. For every satellite at every moment, it sees five things you'd actually know at the time — current elevation, current margin, whether it's rising or setting, distance, and Doppler shift — and predicts how many more seconds that satellite stays above the horizon. The training labels come from real passes: I propagate real orbits, watch each satellite rise and set, and record how long each was actually visible. The model is never shown the future. On held-out test data it predicts remaining visibility to within about fourteen seconds, roughly 84% better than a naive "just guess the average" baseline. And the feature it relied on most was whether the satellite is rising or setting — exactly what physical intuition says. When a model's most important feature matches the physics, that's a good sign it learned something real.

Then I plugged it into the scheduler, and it got worse. I built a scheduler that picks the satellite predicted to stay visible longest, and compared it against Week 3's greedy one over twelve hours of real pass data. Greedy made 78 hand-offs. My clever new ML version made 81. Worse.

I sat with that for a while, because it would have been easy to bury it. But it's real and it's explainable. The flaw is almost obvious in hindsight: a satellite that has just risen has, by definition, the longest remaining visibility of anything in the sky. So "always pick whoever stays longest" keeps abandoning a perfectly good current satellite the instant a fresh one clears the horizon — and every one of those switches is a hand-off. I'd built a scheduler that was permanently distracted by the newest thing in view. Greedy, almost by accident, was stickier.

Once you name the problem, the fix is clear: don't abandon the current satellite unless a rival is clearly better for longer. That reluctance to switch is called hysteresis. I added it — and hand-offs dropped to 72, comfortably below greedy's 78. So the prediction was useful after all, but only once it was paired with an explicit reluctance to switch, not used naively.

Three numbers, one honest arc: greedy 78, naive ML 81, ML with hysteresis 72.

I'm sharing the wrong turn on purpose. I could have written "added AI, hand-offs dropped" — technically true if you only show the first and last numbers. But it would hide the actual engineering, which is that the obvious use of a good model was wrong, and knowing why is what separates understanding a system from just wiring one together. Both the negative result and the fix are locked into the project's automated tests, so they can't quietly drift.

Same honesty note as always: the orbits and visibility are real, live data; the RF power figures used for margin are still estimated from published sources, not operator specs.

Four weeks in. Week 1 built the physics, Week 2 connected it to a real orbit, Week 3 turned it into a decision, and Week 4 brought in a model that genuinely predicts — and taught me that a good prediction used carelessly can still make things worse.

Until next time,
Shaif

Keep Reading