ntn-cho
June 12, 2026 · View on GitHub
Time-to-Exit (TTE)-aware 3GPP Rel-17 Conditional Handover for LEO satellite NTN, in ns-3.43.
- ns-3 version:
release ns-3.43 - Version:
1.0.0 - License: GPL-2.0-only
- Maintainer: Muhammad Uzair, Independent Researcher (ORCID 0009-0002-4104-2680)
See INSTALL.md for setup and the dependency list. This module is also distributed as part of the ns3-ntn-toolkit.
Dependencies
- Required: the SNS3
satellitemodule —NtnOrbitPredictor/NtnTteEstimatoruse itsSatSGP4MobilityModeland antenna-gain patterns for SGP4 propagation and beam geometry. - Examples: the real-stack examples (
ntn-cho-leo-basic,ntn-cho-handover-traffic,ntn-cho-real-stack) additionally use the sibling toolkit modulesntn-traffic(NtnRealStackHelper— real mmwave NR NTN cell with measured traffic) andntn-constellation(Sgp4MobilityModel+WalkerConstellation), plus the in-treemmwaveandltestacks.ntn-cho-full-constellationusesNtnRealisticTrafficHelperfromntn-traffic; in the standalone App Store package this helper is vendored into the module (self-contained). - Optional: the
ns3-aimodule, only forNtnAiInterface(the learning-based path). The C++ triggers build and run without it.
Overview
ntn-cho implements 3GPP Release-17 Conditional Handover (CHO) for Non-Terrestrial Networks (NTN), with a focus on LEO satellite constellations where rapid beam-coverage changes drive frequent, often premature, handovers. The module adds a Time-to-Exit (TTE)-aware candidate selection that admits a target beam only when it will stay in coverage long enough to be worth the switch. Alongside the TTE-aware novelty it implements the NTN handover trigger classes with precise standards positioning — Rel-17 normative CondEvents measurement-based A4-style (event A3 baseline), location-based (CondEventD1) and time-based (CondEventT1, ephemeris-scheduled), the Rel-18 CondEventD2 (distance with MOVING ephemeris-derived reference locations, TS 38.331 §5.5.4.15a), and the TR 38.821 §6-studied elevation-based and timing-advance-based mechanisms (studied, not standardized CondEvents) — plus two forward-looking mechanisms: Rel-19 conditional LTM (L1-filtered measurements with a MAC-CE-style fast cell switch) and trajectory-predictive CHO (forecast serving outage, maximum predicted time-of-stay), with optional RACH-less execution from ephemeris/GNSS TA pre-compensation. It is built around a 3GPP-aligned CHO state machine, an orbit/beam predictor, and a 3GPP TR 38.811 NTN measurement model so that handover decisions fall out of live geometry rather than hardcoded scripts.
What's new
See the CHANGELOG.
- Six NTN trigger classes in
NtnChoAlgorithm(Rel-17 A3/D1/T1 + Rel-18 D2 + TR 38.821-studied elevation/TA;combineWithA4enforces the Rel-17 rule that T1/D1/D2 are configured together with the A4 measurement leg):TRIGGER_EVENT_A3,TRIGGER_LOCATION_D1,TRIGGER_TIME_T1(CondEventT1 handover window from the serving cell's remaining time-of-service),TRIGGER_ELEVATION(serving elevation belowelevationMinDeg, candidate above floor +elevationHystDeg, elevation derived from the ephemeris/GNSS slant range atorbitAltitudeKm), andTRIGGER_TIMING_ADVANCE(serving TA abovetaServingMax, or a candidate at leasttaAdvantagelower). For these classes the admitted set already encodes the standardized condition, so selection takes the strongest measured candidate (max SINR). - Real-stack examples —
ntn-cho-leo-basic,ntn-cho-handover-trafficand the newntn-cho-real-stackrun on a real mmwave NR NTN cell (NtnRealStackHelper: SpectrumPhy + MAC + HARQ + RLC/PDCP + RRC + EPC) with SGP4 Walker satellite orbits and 3GPP TR 38.811 §6.1.1.1 class UE mobility; the serving SINR is measured off the mmwave PHY trace, not closed-form. NtnTr38811MobilityModel— the TR 38.811 UE classes are now a real ns-3MobilityModel(ECEF, SGP4-compatible frame), so the per-class motion drives the radio stack, Doppler, and the TTE estimator directly.- Standards-validation test suite (
ntn-standards-validation) — checks the mobility architecture against orbital theory and published NTN figures (see Build, run & test below). - Doppler is SIGNED in the measurement model — the shift flips from positive to negative across a LEO pass, so approaching vs. receding geometry is modelled correctly.
- CSV sentinel hygiene — no
serving_sat=4294967295orsinr=-100sentinel values leaking intoue_tracks,handover_events, orkpi_timeseries;avg_sinraverages only currently-served UEs; the first-handovertime_of_stayis no longer inflated.
Models, helpers & key classes
Model (model/):
NtnChoAlgorithm(ntn-cho-algorithm.h) — 3GPP Rel-17 CHO algorithm with TTE-aware candidate selection and theCHO_IDLE → CHO_PREPARED → CHO_CONDITION_MONITORING → CHO_EXECUTING → CHO_COMPLETEDstate machine. Trigger types:TRIGGER_EVENT_A3,TRIGGER_LOCATION_D1,TRIGGER_TIME_BASED,TRIGGER_TTE_AWARE,TRIGGER_THZ_BEAM_QUALITY,TRIGGER_LTM_CONDITIONAL(Rel-19 conditional LTM),TRIGGER_TRAJECTORY_PREDICTIVE(PCHO), and the standardized NTN classesTRIGGER_TIME_T1,TRIGGER_ELEVATION,TRIGGER_TIMING_ADVANCE.ChoConfigcarries the per-class parameters (t1WindowDuration,elevationMinDeg/elevationHystDeg,orbitAltitudeKm,taServingMax/taAdvantage, the LTM/PCHO knobs, andrachLess+rachDuration/choExecutionDelayfor RACH-less execution);GetMechanismStats()reports LTM switches, PCHO triggers, RACH-less vs RACH executions, and per-handover interruption.NtnTteEstimator(ntn-tte-estimator.h) — estimates Time-to-Exit for satellite beam coverage, per-candidate and in batch.NtnOrbitPredictor(ntn-orbit-predictor.h) — predicts satellite/beam positions and coverage over time and reports visible satellites and best beams per UE position.NtnMeasurementModel(ntn-measurement-model.h) — computes RSRP/SINR from satellite beams using the 3GPP TR 38.811 NTN channel scenarios.NtnTr38811MobilityModel(ntn-tr38811-mobility-model.h) — the 3GPP TR 38.811 §6.1.1.1 NTN UE classes (handheld static/pedestrian, vehicular, HST, maritime, aviation, fixed IoT) as a real ns-3MobilityModelin ECEF, the same frame as the satellite side's SGP4 models; includes thentngeogeometry utilities (geodetic↔ECEF, elevation, slant range) andNtnTr38811MobilityHelperfor installing UE populations.NtnAiInterface(ntn-ai-interface.h) — ns3-ai shared-memory bridge exposing a candidate-cell observation/action space for AI-driven handover decisions.
Helper (helper/):
NtnChoHelper(ntn-cho-helper.h) — top-level helper that wires up a CHO scenario (channel scenario, trigger type, carrier frequency) and reports aggregated KPI results.NtnRealisticMobilityHelper(ntn-realistic-mobility.h) — generates UE populations with realistic per-class motion following the seven 3GPP TR 38.811 §6.1.1.1 NTN UE classes, with built-in scenario profiles (NtnMobilityScenarios).
Examples
All five examples build under build/contrib/ntn-cho/examples/. Each can be launched either through ./ns3 run or directly via the built binary with LD_LIBRARY_PATH=build/lib.
ntn-cho-leo-basic
Smoke test for the CHO algorithm on a real mmwave NR NTN cell (NtnRealStackHelper): one SGP4 serving satellite, TR 38.811 class UEs under its sub-point, real UDP traffic over the radio, and the CHO algorithm exercised on a 200 ms cadence with the measured per-UE SINR from the mmwave PHY trace.
./ns3 run "ntn-cho-leo-basic --trigger=tte-aware --simTime=12 --numUes=4"
LD_LIBRARY_PATH=build/lib ./build/contrib/ntn-cho/examples/ns3.43-ntn-cho-leo-basic-default --trigger=tte-aware --simTime=12 --numUes=4
Outputs: sim_health.csv (written via NtnRealStackHelper::WriteHealthReport()) in --outputDir, plus the measured mean SINR and throughput on stdout.
Key args: simTime, trigger (a3|location|tte-aware), tteMinimum, numUes, satEirpDbm, outputDir.
ntn-cho-full-constellation
Full Walker constellation NTN-CHO run: multi-beam satellites, proper initial serving assignment, calibrated TTE values and a realistic HO-failure model, with the four algorithms (a3 / location / time / tte-aware) selectable for comparison. A real UDP data plane (via NtnRealisticTrafficHelper) runs alongside the constellation-scale measurement loop.
./ns3 run "ntn-cho-full-constellation --algorithm=tte-aware --numUes=50 --outputDir=/tmp/ntn-full"
LD_LIBRARY_PATH=build/lib ./build/contrib/ntn-cho/examples/ns3.43-ntn-cho-full-constellation-default --algorithm=tte-aware --numUes=50 --outputDir=/tmp/ntn-full
Outputs (in --outputDir): handover_events.csv, measurements.csv, tte_computations.csv, satellite_tracks.csv, ue_tracks.csv, kpi_timeseries.csv, kpi_summary.txt, the GeoJSON layers (satellite_positions.geojson, ue_positions.geojson, beam_footprints.geojson, handover_events.geojson), and sim_health.csv (via NtnRealisticTrafficHelper).
Key args: simTime, numUes, scenario, algorithm (a3|location|time|tte-aware), d1Threshold, qualityTh, tteMinimum, outputDir, rngRun, verbose, numPlanes, satsPerPlane, trafficUes (UEs carrying the real UDP plane; 0 = all).
ntn-cho-handover-traffic
Real UDP downlink to TR 38.811 UEs on a real mmwave NR NTN cell, handed over by the actual NtnChoAlgorithm while the constellation flies real SGP4 Walker orbits: the serving satellite passes zenith and recedes, the in-plane neighbour approaches, and the handover falls out of the genuine orbital crossover. The serving SINR fed to the algorithm is measured from the PHY; the candidate SINR is ephemeris-predicted (measured baseline plus the real Friis slant-range ratio). All nine trigger mechanisms are selectable — including Rel-17 A3/D1/T1, Rel-18 D2 and the TR 38.821-studied elevation/TA classes.
./ns3 run "ntn-cho-handover-traffic --simSeconds=60 --trigger=elevation"
./ns3 run "ntn-cho-handover-traffic --trigger=t1 --rachLess=1"
LD_LIBRARY_PATH=build/lib ./build/contrib/ntn-cho/examples/ns3.43-ntn-cho-handover-traffic-default --simSeconds=60 --trigger=ta
Outputs: sim_health.csv in --outputDir, per-handover lines on stdout (measured serving SINR, predicted candidate SINR, interruption), and a summary line with the measured serving-cell goodput across the handover, mean SINR, SINR at handover, last interruption, and RACH-less execution count.
Key args: simSeconds, numUes, leoAltKm, freqGHz, satEirpDbm, tteMinSec, trigger (tte-aware|ltm|pcho|a3|d1|t1|elevation|ta), rachLess, satsPerPlane, outputDir.
ntn-cho-real-stack
Real-stack flagship: the TTE-aware CHO (or Rel-19 LTM / trajectory-predictive PCHO) decides on the measured mmwave SINR while serving and candidate satellites fly real SGP4 Walker-Delta orbits and the UEs move under TR 38.811 class mobility. The summary reports the mechanism counters (GetMechanismStats()): LTM fast switches, PCHO trajectory triggers, RACH-less vs RACH executions, last interruption, and the last ephemeris-pre-computed TA.
./ns3 run "ntn-cho-real-stack --duration=60 --trigger=pcho --rachLess=1"
LD_LIBRARY_PATH=build/lib ./build/contrib/ntn-cho/examples/ns3.43-ntn-cho-real-stack-default --duration=60 --trigger=pcho --rachLess=1
Outputs: sim_health.csv in --outputDir and the CHO/mechanism summary on stdout (measured mean SINR, measured DL throughput, evaluations, handovers, mechanism counters).
Key args: duration, numUes, altitude, satEirpDbm, freqGhz, tteMin, trigger (tte-aware|ltm|pcho), rachLess, satsPerPlane, outputDir.
ntn-realistic-mobility-demo
Demonstrates the per-class realistic mobility generator: spawns one UE per 3GPP TR 38.811 §6.1.1.1 class and writes its trajectory to CSV for inspection/plotting.
./ns3 run "ntn-realistic-mobility-demo --outputDir=/tmp/mob_demo --simTime=600"
LD_LIBRARY_PATH=build/lib ./build/contrib/ntn-cho/examples/ns3.43-ntn-realistic-mobility-demo-default --outputDir=/tmp/mob_demo --simTime=600
Outputs: mobility_trace.csv in --outputDir.
Key args: outputDir, simTime, dt, rngRun.
Build, run & test
./ns3 configure --enable-examples --enable-tests && ./ns3 build
./test.py -s ntn-cho
./test.py -s ntn-standards-validation
Two test suites ship with the module:
ntn-cho— unit tests for the CHO algorithm, the CHO state machine, and the NTN measurement model.ntn-standards-validation— validates the mobility architecture against orbital theory and published NTN figures: SGP4 propagation vs Keplerian theory (orbital radius, speedsqrt(mu/a), quarter-period arc at 550 km / 53°), the zenith-pass Doppler envelope (Doppler null at culmination, S-band shift inside the published LEO envelope), ENU pass geometry (culmination at zenith, monotonic elevation decay), and the spherical-Earth elevation/slant relation used by the elevation trigger — including the TR 38.821 LEO-600 reference point (~1932 km slant at 10° elevation).
See INSTALL.md for full setup.
Citing
@misc{uzair2026ntncho,
author = {Muhammad Uzair},
title = {ntn-cho: Time-to-Exit-Aware Conditional Handover for
Non-Terrestrial Networks in ns-3},
year = {2026},
note = {ns-3 App Store module, v1.0.0. ORCID 0009-0002-4104-2680}
}
License & author
GPL-2.0-only. See LICENSE.
Author: Muhammad Uzair, Independent Researcher (ORCID 0009-0002-4104-2680).