Skip to content

Latest commit

 

History

33,424 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ISAC node nrUE

OAI UE sim based ISAC system

A fork of Duranta OpenAirInterface that turns the OAI nr-uesoftmodem into a sensing receiver.

An OCUDU RAN transmits standard 3GPP downlink CSI-RS. A receiver co-located on the same mast listens for the reflections and turns them into range-Doppler maps. Nothing is added to the air interface. The waveform stays fully NR-compliant, and the sensing is parasitic on reference signals the network already sends.

Pseudo-monostatic CSI-RS sensing geometry

The observable is the least-squares channel estimate the UE already computes for CSI reporting. The tap adds no PHY processing; it copies estimates that exist anyway and streams them off-box over UDP.

ISAC architecture: RF chain, receiver chain and datasheet


Quick start

The reference setup pairs this UE with an OCUDU RAN driving a LiteON O-RAN RU over DPDK fronthaul, on band n78 at 100 MHz. The ISAC panel antenna and the RU share one mast; a USRP X410 feeds the UE, with a Falcon X GM supplying a common clock and time reference.

ISAC testbed: LiteON RU, ISAC panel antenna, USRP X410, Falcon X GM, OAI UE and OCUDU RAN

# build
cd cmake_targets/ran_build/build
cmake ../../.. -DOAI_USRP=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo
make -j$(nproc) nr-uesoftmodem

# run the UE with the sensing tap enabled
sudo ./nr-uesoftmodem -O <your>.conf \
  --usrp-args "type=x4xx,addr=192.168.20.2,clock_source=external,time_source=external" \
  -r 273 --numerology 1 --band 78 -C 3450720000 --ssb 1518 \
  --ue-nb-ant-rx 2 --ue-nb-ant-tx 1 --ue-rxgain 40 --ue-fo-compensation \
  --ue-timing-correction-disable \
  --uecap_file targets/PROJECTS/GENERIC-NR-5GC/CONF/uecap_ports1.xml \
  --isac-udp 127.0.0.1:5556

CSI-RS only flows to an RRC_CONNECTED UE, so keep traffic on the link or the gNB releases the UE and sensing goes quiet:

sudo bash -c 'until ip -4 addr show oaitun_ue1 2>/dev/null | grep -q inet; \
  do sleep 0.1; done; exec ping -i 0.2 -I oaitun_ue1 8.8.8.8'

Check the raw CSI responds to the scene before trusting any map:

tools/isac/isac_csi_monitor.py --port 5556 --csi-type trs --rx 0

chg% is the sensitive column, because motion rearranges multipath even when total power holds steady. If it does not move when someone walks through, the problem is RF or geometry, not processing.

Then the map:

tools/isac/isac_range_doppler.py --port 5556 --csi-type trs \
  --cpi 32 --min-range 0.5 --max-range 6 --clutter-rank -1 \
  --dyn-range 15 --update-every 25

What this fork adds

file change
openair1/PHY/NR_UE_TRANSPORT/nr_ue_isac.{c,h} new: the sensing tap and UDP wire format
openair1/PHY/NR_UE_TRANSPORT/csi_rx.c force channel estimation when sensing, push each snapshot
executables/nr-uesoftmodem.{c,h} --isac-udp <ip>:<port>
CMakeLists.txt build the tap into PHY_SRC_UE
tools/isac/ receiver, monitor, offline diagnosis, selftest, link budget

Total: two new source files and 17 lines of integration. Everything else is stock upstream.

Tools

tool role
isac_range_doppler.py receiver: range-Doppler map, CA-CFAR, M-of-N tracker. --replay, --record, --headless
isac_csi_monitor.py raw CSI amplitude per occasion. No radar processing
isac_diagnose.py offline: sampling uniformity, delay/amplitude stability, artefact floor
isac_selftest.py 13 checks of the processing chain against synthetic ground truth
isac_link_budget.py radar-equation link budget

Measured characteristics

At 3450.72 MHz, 273 PRB, 30 kHz SCS (λ = 8.69 cm, occupied BW 98.28 MHz):

quantity value set by
range resolution 1.525 m c / (2·B)
unambiguous range 416 m c / (2·Δf), Δf = 360 kHz
direct-path dead zone 2.90 m ≈1.9 × resolution (window mainlobe)
update rate 20 ms CSI-RS / TRS period
unambiguous velocity ±1.09 m/s 20 ms TRS burst repetition
… with --unfold ±43.4 m/s 0.5 ms intra-burst baseline
velocity resolution 0.068 m/s CPI 32 = 0.64 s dwell

The TRS burst has two timescales

TRS arrives as 2 snapshots in adjacent slots, then 19.5 ms idle, repeating every 20 ms. That is ~100 estimates/s on average, but aliasing follows the 20 ms repetition, not the average. The tight pair adds no independent slow-time sample, it only says where inside the burst each one sat. Deriving the velocity axis from the mean rate reports twice the span that exists, and static clutter aliases into the surplus half as symmetric false pairs.

--unfold recovers the short baseline to resolve the fold.

CSI-RS cadence is a hard 3GPP limit

csi_rs_period accepts {10, 20, 40, 80} ms, but TS 38.214 §5.1.6.1.1 forbids 10 ms above 52 RB. At 273 RB, 20 ms / 50 Hz is the floor. Getting below it means dropping to ≤52 RB, which takes range resolution from 1.53 m to ~8 m.


Status and limitations

Read this before drawing conclusions from a map.

Verified working

  • Processing chain: isac_selftest.py passes 13/13: range and velocity scale, sign convention, resolution, clutter-rank safety, CFAR + tracker, radar-equation range, common-mode notch.
  • Motion is detected. Against a still room, a person at ~1.5–2 m raises the per-occasion channel-change metric from a 10.6 ± 0.55 baseline to peaks of 40–49 (≈13 dB margin).

The principal limitation: the range axis does not track

Range rate dR/dt and Doppler velocity v are independent measurements of the same motion, so a resolved target correlates near +1. Measured over a 260 s ground-truth walk/stand session:

[range-check] corr(v, dR/dt) = +0.055 over 313 detections -- range is NOT tracking

The target is detected as a modulation of the direct-path leakage, and that leakage sits at delay 0 regardless of where the person stands. Doppler responds to motion; the range coordinate is pinned to the leakage.

Treat this as a motion/presence sensor with a Doppler measurement, not a ranging radar. The fix is physical: antenna isolation, polarisation, tilt, separation. --range-check scores any such change in about a minute, which is far more reliable than judging heat maps by eye.

Other things worth knowing

  • Range goes as the fourth root of the target-to-coupling ratio: 1 dB of isolation buys ~5.9% range, and doubling range costs 12 dB.
  • A map of many cells reaches ~10 dB above its own median on noise alone. The tool prints that ceiling, so always compare the peak against it before calling anything a target.
  • Record an empty room first. A fixed mechanical line was confirmed as a target in essentially every frame of one session. --notch VELOCITY removes it.
  • Close in, the adaptive subspace canceller nulls targets that share the direct path's subspace, and reports better cancellation while doing it. Use --clutter-rank -1 under ~3 m.

About

ISAC node nrUE is developed by coRAN LABS.

Upstream

This is a fork of Duranta OpenAirInterface, which delivers and maintains an open-source cellular wireless software stack for 4G, 5G and future networking technologies. For upstream documentation, repository structure and community support, see the OAI documentation and openairinterface.org.

License

The source code is distributed under CSSL v1.0. Some files, such as for orchestration, are distributed under MIT license. Documentation is distributed under Creative Commons Attribution 4.0 International license.

All the files without an explicit copyright header have an implicit "Copyright of OpenAirInterface Authors".

Please see NOTICE for other licenses which are used in the software.

In the past OAI source code has been re-licensed sometimes, here is the history:

  1. CSSL v1.0 starting tag 2026.w14
  2. OAI Public License v1.1 starting tag v1.0 till af4b0d53
  3. OAI Public License v1.0: starting tag v.04 till v1.0
  4. GPL 3: starting tag v.0 till v.04 (only initial implementation of 4G)

About

No description, website, or topics provided.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages