UAV Systems Engineering · Module 2
M2-T1: GNSS fundamentals
Four satellites, four unknowns: derive the pseudorange equation, solve it by Gauss–Newton, and see why geometry matters as much as signal.
GNSS is the aerial robot’s global reference: the only sensor that does not drift. To design a system that survives its loss you first need to know what it actually measures, how accurate that is, and what can break it.
Learning objectives
After this lesson, you should be able to:
- Write the pseudorange measurement equation and name its terms.
- Explain why four satellites are required for a 3-D position and clock solution.
- Solve for position and clock bias with Gauss–Newton least squares.
- Interpret dilution of precision (DOP) as a geometry factor on position error.
Conceptual explanation
Each GNSS satellite broadcasts its position and the time at which it sent the signal. The receiver subtracts this from its own clock to get a travel time, multiplied by the speed of light: the pseudorange. It is “pseudo” because the receiver’s clock is cheap and wrong by an unknown amount, which adds the same error to every range.
A receiver therefore estimates four numbers: three position coordinates and the receiver clock bias. With more satellites in view the system is over-determined and solved by least squares.

Engineering intuition
Three known distances would fix a point in 3-D if the clock were perfect. The clock error shifts every range by the same amount, so a fourth satellite is needed to find it. Position accuracy then depends on two things: the accuracy of each range (the user equivalent range error) and the geometry of the satellites. Satellites clustered in one part of the sky give nearly parallel lines of sight and a poorly conditioned solution; spread-out satellites give a well-conditioned one. DOP summarises that conditioning.
Vertical accuracy is worse than horizontal accuracy because all satellites are above the horizon: no satellite constrains the solution from below.
Mathematical formulation
For satellite at known position and receiver at unknown position with clock bias (in seconds), the pseudorange is:
- measured pseudorange (m).
- ,
- satellite and receiver positions in the same Earth-fixed frame.
- speed of light, 299 792 458 m/s.
- receiver clock bias; is the same distance error for every satellite.
- remaining errors: satellite clock and orbit, ionosphere and troposphere delay, multipath, receiver noise (lesson M2-T4).
Linearise about an estimate (, ): with unit line-of-sight vectors ,
With independent range errors of standard deviation , the covariance of the solution is . The dilution of precision is built from the diagonal of :
Architecture and data flow
Antenna → RF front-end → tracking loops (per satellite) → pseudorange and carrier-phase measurements → navigation solution (position, velocity, time) with quality indicators (satellite count, DOP, accuracy estimates, fix type) → autopilot. The autopilot should consume the receiver’s quality indicators, not only the position: they are what lets a monitor decide to stop trusting GNSS (lesson M8-T11).
Real-world UAV applications
- Absolute position reference for navigation, geofencing and return-to-home.
- Bounding drift of inertial and visual odometry in a GNSS-aided estimator.
- Time reference: GNSS provides time for sensor synchronisation (lesson M7-T8).
- Pre-flight go/no-go: required satellite count, HDOP and fix type before arming.
Implementation example
This runs as shown. It builds a synthetic constellation, simulates pseudoranges with a 100 km clock-bias-equivalent and noise, solves by Gauss–Newton, and computes DOP.
import numpy as np
rng = np.random.default_rng(1)
c = 299_792_458.0
R_orbit = 26_560e3 # GPS-like orbital radius (m), illustrative geometry
truth = np.array([6_371e3, 0.0, 0.0]); b_true = 1e-4 # receiver on the "equator" (m), clock bias 0.1 ms
az_el = [(0, 80), (90, 35), (180, 25), (270, 40), (45, 55)] # satellite directions (deg): azimuth, elevation
def sat_pos(az, el):
az, el = np.radians(az), np.radians(el)
up = truth / np.linalg.norm(truth); east = np.array([0, 1.0, 0]); north = np.cross(up, east)
d = np.cos(el) * (np.cos(az) * north + np.sin(az) * east) + np.sin(el) * up
# ray from the receiver along d meets the orbit sphere:
t = -truth @ d + np.sqrt((truth @ d) ** 2 - truth @ truth + R_orbit ** 2)
return truth + t * d
S = np.array([sat_pos(a, e) for a, e in az_el])
sigma = 3.0 # per-satellite range error, m
rho = np.linalg.norm(S - truth, axis=1) + c * b_true + sigma * rng.standard_normal(len(S))
x = np.array([6_000e3, 100e3, -100e3, 0.0]) # initial guess [r, c*b]: ~400 km off
for _ in range(10):
rng_hat = np.linalg.norm(S - x[:3], axis=1)
u = (S - x[:3]) / rng_hat[:, None]
H = np.hstack([-u, np.ones((len(S), 1))])
dx, *_ = np.linalg.lstsq(H, rho - (rng_hat + x[3]), rcond=None)
x = x + dx
if np.linalg.norm(dx) < 1e-6: break
err = np.linalg.norm(x[:3] - truth)
Q = np.linalg.inv(H.T @ H)
pdop = np.sqrt(np.trace(Q[:3, :3]))
print(f"position error {err:.1f} m, clock bias error {(x[3]/c - b_true)*1e9:.1f} ns, PDOP {pdop:.2f}")
assert err < 30 and pdop < 5 and abs(x[3] / c - b_true) < 1e-7
# poor geometry: all satellites near one direction -> much larger DOP
S2 = np.array([sat_pos(a, e) for a, e in [(0, 60), (10, 62), (350, 58), (5, 65), (20, 60)]])
u = (S2 - truth) / np.linalg.norm(S2 - truth, axis=1)[:, None]
H2 = np.hstack([-u, np.ones((5, 1))]); pdop2 = np.sqrt(np.trace(np.linalg.inv(H2.T @ H2)[:3, :3]))
print("clustered satellites PDOP:", round(pdop2, 1)); assert pdop2 > 3 * pdopCommon engineering mistakes
Treating position as the only output
The receiver also reports velocity (from Doppler), time and accuracy estimates; ignoring quality indicators removes your best integrity signal.
Assuming more satellites always means better accuracy
Geometry and error quality matter. Low-elevation satellites carry more atmospheric and multipath error.
Using GNSS height as precise altitude above ground
Vertical error is larger than horizontal and the height is above an ellipsoid or geoid, not above ground.
Ignoring receiver update rate and latency
A 5 Hz fix with 100–200 ms latency is stale at 15 m/s: model the delay in the estimator.
Failure modes
| Failure mode | How it shows up | Likely cause |
|---|---|---|
| Poor geometry | Large reported DOP, jumping position | Satellites blocked by buildings or terrain, leaving a narrow cone of sky |
| Receiver cold start | No fix for tens of seconds after power-up | Almanac or ephemeris unavailable; wait for a fix before arming |
| Fix type degradation | Receiver drops from RTK fixed to float or to a plain 3-D fix | Lost corrections or too few satellites, reducing accuracy from centimetres to metres |
| Antenna interference | Low carrier-to-noise ratio, intermittent fix | Interference from companion computer, USB 3 or camera electronics near the antenna |
Debugging approach
- Log satellite count, HDOP/VDOP, fix type and the receiver’s horizontal accuracy estimate alongside the position.
- Plot carrier-to-noise density (C/N0) per satellite: a low value on all satellites points to antenna placement or interference.
- Compare against a second receiver or a surveyed point on the ground before flying.
- Move the antenna away from the companion computer and USB 3 cables, and re-check C/N0.
Practical exercises
- Show that three pseudoranges leave a one-parameter family of solutions when the clock bias is unknown.
- Compute HDOP and VDOP for the code example and explain why VDOP is larger.
- Change the constellation so that all satellites are above elevation. What happens to the DOP?
- If and PDOP = 2, what is the expected position error?
Interview questions
Write an answer in your own words, then reveal the model answer. Nothing is sent anywhere.
Question 1
Why do you need four satellites for a 3-D fix?
Model answer
There are four unknowns: , , and the receiver clock bias. Each pseudorange gives one equation, so four are needed; more make the problem over-determined and allow least-squares and integrity checks.
Question 2
What does DOP tell you?
Model answer
How satellite geometry amplifies range errors into position errors: position error ≈ DOP × range error. It is a property of geometry, independent of signal quality.
Question 3
Why is GNSS vertical accuracy worse than horizontal?
Model answer
All satellites are above the horizon, so no line of sight constrains the vertical solution from below; VDOP is therefore larger than HDOP.
References and further reading
Primary papers, official documentation and standards. Each claim above that is specific to a tool or version points here.
- . . Groves, Principles of GNSS, Inertial, and Multisensor Integrated Navigation Systems, 2nd ed., Artech House, 2013, chapters 8–9.
- GPS.gov: U.S. government GPS information (performance standards and accuracy statements)
- ESA Navipedia: GNSS fundamentals, error budgets and DOP