Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NTN 5G Pre-compensation

Week 5 showed that standard 5G NR cannot reach a satellite: the timing advance needed was 14× beyond the standard's limit, and 0% of a real pass fitted inside it. This project implements the fix 3GPP actually specifies — Release-17 GNSS-assisted pre-compensation — over a real satellite pass, and asks the question the fix leaves open: how fresh does the correction have to be?

This is Week 6 of a 12-week series. It is the direct sequel to ntn-5g-timing-doppler (Week 5).

Run it in 2 minutes

pip install -r requirements.txt
python -m aiprecomp.main

Fetches live Starlink TLEs, finds a real pass over Aberdeen, runs Rel-17 pre-compensation at S-band, prints both findings, and saves ntn_precomp_residuals.png.

python -m pytest

Runs the test suite (8 tests, all passing).

What Release-17 actually specifies

The network doesn't correct each user's delay and Doppler individually — that wouldn't scale. Instead the work moves to the handset:

  1. The satellite broadcasts its ephemeris (position + velocity) in a System Information Block.
  2. The UE is required to have GNSS, so it knows its own position.
  3. From both, the UE computes its own distance and radial velocity to the satellite.
  4. It pre-computes and applies the timing advance and Doppler correction to its uplink before transmitting.

The signal arrives at the satellite already corrected, so the base station can operate as though it were serving an ordinary terrestrial cell.

The two findings

Finding 1 — pre-compensation works, and it isn't close

With a fresh correction, the residual is essentially zero. On a real pass of STARLINK-1008 over Aberdeen the uncompensated impairment was 9,860 µs of timing advance and 39,756 Hz of Doppler; after pre-compensation, both drop to nothing.

This is worth being precise about: with perfect knowledge and zero delay the correction is exact by construction, not by discovery. That's not a cheat — it's the point. The scheme is geometrically exact. The engineering question isn't whether it works, it's what breaks it.

Finding 2 — it must be refreshed every ~100 ms, and timing breaks first

A LEO satellite moves several km/s, so a correction is stale the moment it's computed. Sweeping the age of the applied correction against the 3GPP tolerances:

Constraint Tolerance Max refresh interval
Residual timing error cyclic prefix, 4.69 µs @ 15 kHz SCS ~100 ms
Residual frequency error ±0.1 ppm = ±200 Hz @ 2 GHz (TS 38.101-5) ~400 ms

Timing is the binding constraint — roughly 4× stricter than frequency. That isn't obvious going in: Doppler is the impairment people talk about, but on this pass it's the timing that fails first. A correction just one second old already blows the cyclic prefix by ~8.5×.

A closed-form cross-check

Residual timing error grows at 2 · range_rate / c per second of staleness, so the timing-limited refresh interval should be about:

max_refresh ≈ CP · c / (2 · max_range_rate)

For the STARLINK-1008 pass this gives 118 ms, against 100 ms from the swept simulation (the largest grid point below it). Two independent methods agreeing is the reason to trust either. Both are locked into the tests.

A third result: GNSS accuracy is a non-issue

A realistic 5–10 m GNSS position error consumes only ~3–6% of the timing budget. You'd need a position error of roughly 180 m before GNSS alone broke the cyclic prefix. Compared to staleness, which blows it in under half a second, GNSS accuracy simply isn't the problem — the refresh rate is.

What is real and what is a published standard value

Quantity Source
Satellite orbit, pass geometry, slant range, range rate Real — live TLE from Celestrak, SGP4 propagation
Timing advance, Doppler, residuals computed from that geometry Real — direct physics
Residual frequency tolerance (±0.1 ppm for NTN UE) Published 3GPP — TS 38.101-5
Cyclic prefix duration (4.69 µs @ 15 kHz SCS, normal CP) Published 3GPP — TS 38.211 numerology

One honest caveat. The ±0.1 ppm figure is a formally specified NTN UE requirement, defined against the ideally pre-compensated reference uplink frequency — exactly a limit on residual Doppler. The cyclic prefix, by contrast, is not a formally specified "maximum residual timing advance." It's used here as the physically meaningful yardstick: uplink symbols must land inside the CP window or they smear into the next symbol. It's the right constraint and the right order of magnitude, but it is my chosen benchmark, not a quoted 3GPP limit.

References

  • Rel-17 UE-side pre-compensation using GNSS + broadcast ephemeris — 3GPP NTN overview (3gpp.org/technologies/ntn-overview); Ericsson, Satellite direct-to-device communication; Lin et al., 5G from Space: An Overview of 3GPP Non-Terrestrial Networks (arXiv:2103.09156).
  • NTN UE residual frequency accuracy, ±0.1 ppm vs ideally pre-compensated reference — 3GPP/ETSI TS 38.101-5.
  • Cyclic prefix durations by subcarrier spacing — 3GPP TS 38.211.

Project structure

ntn-5g-ntn-precomp/
├── aiprecomp/
│   ├── tle_fetch.py       # live TLEs from Celestrak
│   ├── pass_geometry.py   # one real pass: range + range rate over time
│   ├── timing_doppler.py  # TA and Doppler physics (from Week 5)
│   ├── nr_tolerances.py   # the 3GPP limits residuals must fit inside
│   ├── ue_precomp.py      # the Rel-17 UE: GNSS + ephemeris -> correction
│   ├── analysis.py        # both findings + closed-form cross-check
│   └── main.py            # ties it together, produces the plot
├── tests/
│   ├── sample_tle.py      # verified real-format TLE
│   └── test_precomp.py
├── requirements.txt
├── LICENSE
└── README.md

Part of a wider series

Week 6 of a 12-week public engineering portfolio combining AI, 5G/6G and satellite communications. Week 1: link budget · Week 2: pass predictor · Week 3: multi-sat scheduler · Week 4: ML predictor · Week 5: timing & Doppler.

About

Implements 3GPP Release-17 GNSS-assisted TA and Doppler pre-compensation over a real satellite pass, and measures how often it must be refreshed

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages