Pseudorange
The "almost-distance" a receiver actually measures
Why it matters
Real receivers never measure true distance; they measure pseudorange. Recognizing the receiver clock as a shared unknown is what upgrades trilateration into a solvable GNSS positioning problem — and is the reason positioning needs one extra satellite.
Prerequisites
Your phone is lying to itself (and that's fine)
A GPS satellite carries an atomic clock so precise it would lose about a second every few million years. Your phone carries a clock that costs roughly nothing and drifts if you look at it funny. And the entire plan is for the cheap clock to figure out where it is by timing signals from the expensive one.
What could possibly go wrong?
Here is the trouble in one line. A receiver finds distance by measuring how long a signal took and multiplying by the speed of light. But light covers about 30 centimeters every nanosecond. So if the receiver's clock is off by a single microsecond — a rounding error by human standards — every distance it computes is wrong by 300 meters. Your "you are here" dot would land in the next neighborhood.
The idea, before any mathematics
In trilateration we assumed the distances were honest. Drop that assumption and meet the receiver clock: a confident liar. It is wrong — but, crucially, it is wrong by the same amount for every satellite it listens to at the same instant. If its clock is fast by 200 nanoseconds, then every travel time looks 200 nanoseconds too long, so every distance looks the same ~60 meters too far.
That shared wrongness is the whole story, and it has a name: the receiver clock bias. Because the receiver can never fully trust its own ranges, we stop calling them ranges and start calling them pseudoranges — "almost-distances." The prefix pseudo is not false modesty; it is an honest confession baked into the vocabulary.
Now here is the beautiful part. A liar who tells different lies is hopeless. But a liar who tells the same lie to everyone is wonderfully easy to catch — because the single lie becomes just one more thing to solve for. The clock bias is not noise to be feared; it is an unknown to be estimated, exactly like the x and y of your position.
Seeing it
Picture the range circles from trilateration again. A positive clock bias inflates every circle by the same amount, like blowing up a set of balloons in perfect unison. The circles that used to meet at your true position now overshoot it and cross somewhere else entirely — and if you nudge the bias further, that false meeting point keeps sliding away.
The fix is not to pop the balloons. It is to let the solver ask, "What single amount of over-inflation, plus what position, best explains all these circles at once?"
Try it yourself
Four blue stations (think of them as satellites) surround the green receiver — the true position. The clock bias slider adds one shared offset to every measured range. The orange cross is the computed estimate.
Start with the switch off ("naive trilateration") and drag the clock bias away from zero. Watch the estimate abandon the truth and keep drifting — the naive solver blames the geometry for an error that is really about time. Now flip the switch on ("solve for the clock too"). The estimate snaps back onto the receiver, and the panel reports the hidden bias it just uncovered.
This one offset is added to every range at once — the signature of a clock that is wrong, but wrong by the same amount for everyone.
- Mode
- Naive trilateration
- True position
- (58.0, 56.0) m
- Estimated position
- (57.6, 53.1) m
- Position error
- 2.95 m
Slide the clock bias with the switch off: the orange estimate drifts off the truth and keeps sliding — the receiver has no idea its clock is lying. Now flip the switch on: the estimate snaps back and the hidden bias is recovered. That fourth unknown is the whole trick.
Play until one thing feels inevitable: the clock error was never invisible — the naive solver just had no slot to put it in. Give the math one more unknown, and the lie has nowhere left to hide.
Now the mathematics
Let the unknown position be (we stay in 2D here; 3D just adds ), let satellite sit at , and let be the receiver clock bias expressed as a range offset in meters. The model for pseudorange is:
where is the small per-measurement noise. Note carefully that carries no subscript : it is the same term in every equation. That is the mathematical statement of "one shared lie."
We now have three unknowns in 2D — , , and — so we need at least three pseudoranges. (In 3D the unknowns are , , , , which is precisely why GNSS needs a fourth satellite: not for a fourth spatial dimension, but for the clock.) We choose the unknowns that minimize the squared residuals:
Because the range term is non-linear, we linearize and iterate (Gauss–Newton). The Jacobian row for satellite is:
The first two entries are the familiar geometric direction toward the satellite. The trailing is the derivative with respect to the clock bias — and it is a for every satellite, which is the Jacobian quietly agreeing that the bias affects everyone equally. That column of ones is the clock's fingerprint.
How this appears in engineering
In a real receiver the pseudorange is formed from the signal's code phase — how far the received code has slipped relative to the receiver's own replica — scaled by the speed of light:
with both timestamps kept in their respective clocks. Beyond the receiver clock bias, the raw pseudorange also absorbs satellite clock error (removed using broadcast clock parameters), ionospheric and tropospheric delays, and multipath. The receiver clock term is the largest and is estimated every epoch alongside position, because a free-running quartz oscillator drifts far too quickly to calibrate once and forget. This is also why a GNSS receiver, almost as a side effect of locating itself, ends up being an excellent clock — timing and positioning are two answers from the same set of equations.
Check your understanding
- Why is the clock bias written as b and not bᵢ, and what would break if each satellite had its own independent clock error?
- In the interactive, with the switch off, why does the estimate keep drifting as you increase the bias instead of settling on a fixed wrong point?
- In 3D there are four unknowns. Explain, in one sentence, why that forces a fourth satellite even though space has only three dimensions.
- The clock bias is shared; measurement noise is not. Why does that difference let the solver separate the bias from position but not eliminate the noise?
Where to go next
Pseudorange explains what a receiver truly measures and why the clock joins the unknowns. But notice something you may have felt while dragging: when the stations bunch together, the estimate gets twitchy, and when they spread out, it feels rock-solid. That sensitivity of the answer to the geometry of the satellites is the subject of dilution of precision.
Common misconceptions
- A receiver measures true distance to each satellite. It does not: it measures travel time with its own imperfect clock, so every range is offset by an unknown amount.
- The clock error is different for each satellite. To first order it is the same for every satellite measured at the same instant — that shared-ness is exactly what makes it separable from position.
- You can just calibrate the clock error away once. The receiver clock drifts continuously, so the bias is re-estimated at every single epoch.
Key takeaways
- A pseudorange is a true range plus a common receiver-clock offset (expressed in meters).
- The clock bias is one shared unknown, not one per satellite.
- Solving for position and clock together adds a fourth unknown, so 3D positioning needs four satellites (three suffice for 2D position plus clock).
- Ignoring the clock does not just shift the answer a little — the error grows with the bias and never converges to the truth.