README.md

June 27, 2026 · View on GitHub

ntn-v2x

SUMO TraCI Bridge and V2X-LEO Direct / Relay Channels for Vehicular and Maritime NTN Research

NTN-assisted V2X for rural and remote roads: SUMO-driven vehicle mobility, a direct-vs-satellite-relay decision per vehicle made on the measured SINR of a real mmwave NR LEO cell, and a URLLC platoon-control flagship with edge-AI placement — plus a 2-D maritime scenario.

Part of ns3-ntn-toolkittoolkit / INSTALL.


module live demo

Overview

Vehicular networking research has historically lived in OMNeT++ via Veins. Veins is excellent but cannot be lifted into ns-3 without a parallel discrete-event kernel — and the rest of the 6G NTN toolkit is firmly in ns-3. ntn-v2x mirrors what Veins offers in spirit (a SUMO-driven mobility feed plus vehicular channel models) but builds it natively against the ns-3 mobility stack, and puts the radio on a real NR protocol stack:

  • Vehicle FCD replay via SumoTraciBridge — drive ns-3 mobility from SUMO floating-car-data (time,vehid,x,y,z,speed) for offline, bit-reproducible runs, or from a live TraCI v20+ socket.
  • Direct vs satellite-relay decision on measured radio — vehicles are UEs on a real mmwave NR NTN cell (NtnRealStackHelper, SGP4 LEO); each vehicle's direct uplink quality is its measured DL SINR minus a 3GPP-style per-vehicle NLOS blockage loss, and a vehicle that cannot clear minDirectSnr relays through the nearest in-range peer (maxV2vRange).
  • Closed-form referenceV2xLeoDirect keeps the free-space PL + SNR + elevation budget as a comparison baseline; ntn-v2x-real-stack prints it next to the measured SINR so the formula-vs-measurement gap is visible.
  • Measured traffic KPIs — data-plane examples carry NtnOranApplication traffic with an in-band NtnOranPayloadHeader; NtnOranSink measures one-way delay, jitter, PDR and goodput from the packets themselves.
  • Maritime scenario — 2-D vessel mobility (5–13 m/s merchant cruising) that stays bounded inside the sea area across multi-hour runs.
SUMO  ──TCP TraCI──►  SumoTraciBridge  ──MobilityModel.SetPosition──► ns-3
   │                       │  (or trace-replay from FCD CSV)
   │                       └──► per-vehicle samples (TracedCallback)
   ▼                                                                    ▼
[SUMO live]                                              [real mmwave NR LEO cell]

What's new (June 2026)

See the CHANGELOG for the full history.

  • New flagship example ntn-v2x-edge-urllc — a V2X platoon on a real LEO mmwave NR cell with a URLLC platoon-control slice (5QI 82) and an eMBB sensor slice, a hazard-detection xApp consuming measured KPM features every 100 ms, and --edge=sat vs --edge=ground inference placement. The measured decision latency (feature sense → brake command applied) is the experiment outcome, alongside 5GAA-style measured one-way-delay / PDR KPIs.
  • New ntn-v2x-real-stack example — every vehicle is a UE on a real mmwave NR NTN cell; the direct-vs-relay decision rides the measured per-UE DL SINR, with the superseded V2xLeoDirect closed-form value printed next to it for comparison.
  • ntn-v2x-rural-highway converted to measured radio — the direct/relay/orphan split is now driven by the measured baseline SINR of a real cell (minus per-vehicle blockage), not the closed-form budget; the CSV's last column is now measured_baseline_db.
  • ntn-v2x-leo-relay-traffic migrated to NtnOranApplication — BSM rate / latency / jitter / loss are measured end-to-end by NtnOranSink from the in-band payload header (OnOffApplication and FlowMonitor are gone).

Models, helpers & key classes

HeaderProvides
model/sumo-traci-bridge.hSumoTraciBridge — single API for live TraCI (ConnectTcp("127.0.0.1", 8813)) and offline FCD replay (LoadFcdTrace(csv)); RegisterVehicle(), Step() advances regardless of source; tracks per-step sync jitter (GetLastJitterSec() / GetMaxJitterSec()) and exports per-vehicle samples via a TracedCallback.
model/v2x-leo-direct.hV2xLeoDirect — closed-form vehicle ↔ LEO uplink budget (free-space PL + SNR + elevation); ComputeStatic callable inside hot loops without Object allocation overhead. Kept as a reference baseline — the examples decide on measured SINR.
model/v2x-leo-relay.hV2xLeoRelay — V2V-via-LEO relay assignment; each vehicle uplinks direct or relays through the best peer within m_maxV2vRangeM; m_minDirectSnrDb sets the prefer-relay threshold; EvaluateAll() returns the per-vehicle decision.
model/maritime-scenario.hMaritimeMobilityModel — DEPRECATED / offline-test-only synthetic box-bounce vessel motion. The real maritime path reuses ntn-sagin AisMobilityModel (recorded AIS replay) via the ntn-v2x-maritime-ais example.
helper/ntn-v2x-helper.hDeterministic CI fixture writer WriteDeterministicTestFcdCsv — a disclosed, RNG-free FCD-format CSV trace for the test suite only (fixed per-vehicle speed ramp). The shipped example traces are likewise synthetic constant-speed FCD-format CSV fixtures (not SUMO microsimulations; the loader reads a CSV dialect, not SUMO's native fcd-output XML). Examples require an --fcdTrace/--trace CSV file (see traces/); a CSV converted from a SUMO fcd-export also works.

Examples

Build all examples with ./ns3 configure --enable-examples --enable-tests && ./ns3 build. Each example produces the binary build/contrib/ntn-v2x/examples/ns3.43-<name>-default.

ntn-v2x-edge-urllc (flagship)

A two-vehicle highway platoon (100 km/h, 50 m headway) rides a real mmwave NR NTN cell from an SGP4 LEO:

  • URLLC slice (5QI 82, SST 2): periodic platoon-control messages — 5GAA-style KPIs (one-way delay against a < 100 ms target, PDR, jitter) measured in-band by NtnOranSink;
  • eMBB slice (5QI 2, SST 1): sensor/diagnostics upload.

A hazard-detection xApp (OranNtnOnnxXapp: an .onnx model when ONNX Runtime is built in, a registered heuristic otherwise) consumes the URLLC flow's measured KPM feature window every 100 ms and decides whether to issue a brake command. The inference runs --edge=sat (on the regenerative payload, processing-only E2 latency) or --edge=ground (slant-range/c + core), via OranNtnRicPlacement; the decision rides the placement latency both ways (KPM up, command down), so the measured decision latency is the sat-vs-ground experiment outcome. Run both and compare:

./ns3 run "ntn-v2x-edge-urllc --edge=sat"
./ns3 run "ntn-v2x-edge-urllc --edge=ground"

Outputs:

  • Console: 5GAA-style measured KPIs for the control flow (one-way delay vs the 100 ms target, PDR, jitter) and a summary with inference mode, decision count, mean decision latency, brake commands and measured cell SINR.
  • sim_health.csv and kpm_series.csv in --outputDir.

Key args: --simSeconds (sim duration, s) · --edge (inference placement: sat | ground) · --outputDir.

ntn-v2x-rural-highway

A LEO pass over a rural highway: vehicles replayed from a SUMO FCD trace (SumoTraciBridge, trace-replay mode, so CI needs no live SUMO) decide direct-vs-relay-vs-orphan each tick. The LEO link quality is measured off a real mmwave NR cell over representative highway terminals; each vehicle's direct uplink SINR is that measured baseline minus its NLOS blockage, so the direct/relay/orphan split is driven by the measured radio.

./ns3 run "ntn-v2x-rural-highway --vehicles=40 --simTime=30"

Outputs:

  • Per-second CSV at <outputDir>/ntn-v2x-rural-highway.csv with columns time_s,n_direct,n_relay,n_orphan,direct_pct,jitter_ms,measured_baseline_db.
  • sim_health.csv in --outputDir.

Key args: --vehicles (number of vehicles) · --simTime (sim duration, s) · --numCellUes (representative real-cell terminals) · --satEirpDbm (satellite EIRP / gNB Tx power, dBm) · --blockageDb (NLOS blockage on shadowed vehicles, dB) · --dt (TraCI tick, s) · --trace (FCD CSV trace path; generated if missing) · --minDirectSnr (minimum dB for direct uplink) · --maxV2vRange (max V2V range, m, for relay) · --outputDir.

ntn-v2x-real-stack

Every vehicle is a UE on a real mmwave NR NTN cell (SpectrumPhy + MAC + HARQ + RLC/PDCP + RRC + EPC), so each vehicle's direct LEO link quality is the measured per-UE DL SINR. NLOS vehicles carry an additional blockage loss; a vehicle whose measured-minus-blockage SINR falls below the threshold relays through the nearest in-range peer. A mid-run elevation descent collapses the baseline so relay decisions actually flip over the pass. The summary prints the old V2xLeoDirect closed-form SNR next to the measured value.

./ns3 run "ntn-v2x-real-stack --duration=20 --numVehicles=8"

Outputs: console summary (closed-form vs measured UE0 SINR, measured cell SINR/throughput, direct/relay/outage decision counts); sim_health.csv in --outputDir.

Key args: --duration (s) · --numVehicles · --altitude (satellite altitude, km) · --satEirpDbm · --blockageDb (NLOS blockage on shadowed vehicles, dB) · --minDirectSnr (dB) · --maxV2vRange (m) · --outputDir.

ntn-v2x-leo-relay-traffic

A real 2-hop data plane: a shadowed vehicle (veh0) relays basic-safety messages through a peer vehicle (veh1) and a LEO satellite to a ground server (veh0 → veh1 → LEO → server), with real IPv4 forwarding. Each hop's propagation delay is the real slant range / c, and a hop carries traffic only while in contact — the V2V hop within range, the uplink above the minimum elevation. Delivered BSM rate / latency / jitter / loss are measured end-to-end by NtnOranSink from the in-band NtnOranPayloadHeader; the V2xLeoRelay engine logs when veh0 must relay vs go direct.

./ns3 run "ntn-v2x-leo-relay-traffic --simSeconds=60 --bsmHz=10"

Outputs: per-second contact/decision trace and a measured end-to-end summary (BSM txPackets, rxPackets, PDR, delay, jitter) on the console.

Key args: --simSeconds (s) · --bsmHz (basic-safety-message rate, Hz) · --bsmBytes (BSM payload, bytes) · --leoAltKm · --satSpeed (LEO ground-track speed, m/s) · --relayDriftMps (relay vehicle relative speed, m/s) · --maxV2vRange (m) · --minDirectSnr (dB) · --linkCapacityMbps (per-hop P2P capacity) · --outputDir.

Build, run & test

./ns3 configure --enable-examples --enable-tests
./ns3 build
./test.py -s ntn-v2x

The ntn-v2x suite has 5 unit tests: trace-replay sync jitter under the 100 ms gate, V2X-LEO direct free-space path loss within 0.1 dB of the closed form, relay fall-back to a peer when direct SNR is below threshold, maritime bounded mobility, and a 100-vehicle / 5-min replay that must complete inside the test budget.

Live SUMO co-simulation

ConnectTcp() opens a real TCP connection to a TraCI endpoint (and fails gracefully when no SUMO is listening), but the live wire codec is deliberately minimal: live Step() only advances the clock without decoding TraCI messages. FCD replay (LoadFcdTrace(csv)) is therefore the supported path. The public API is identical for both modes, so a full TraCI client can be dropped in later without changing callers.

See INSTALL.md for full setup, dependencies and build notes.

License & author

GPL-2.0-only — see LICENSE.

Muhammad Uzair, Independent Researcher.

@misc{uzair2026ntnv2x,
  author = {Uzair, Muhammad},
  title  = {ntn-v2x: SUMO TraCI Bridge and V2X-LEO Channels for ns-3.43},
  year   = {2026},
  url    = {https://github.com/Muhammaduazir69/ntn-v2x}
}