OpenISAC

A Versatile and High-Performance Open-Source Platform for Real-Time ISAC Experimentation

Get Started

About OpenISAC

Integrated sensing and communication (ISAC) is envisioned to be one of the key technologies in 6G. OpenISAC is a versatile and high-performance open-source platform designed to bridge the gap between theory and practice.

Built entirely on open-source software (UHD + C++ + Python), it supports real-time OFDM-based sensing and communication. A key feature is its novel over-the-air synchronization mechanism, enabling robust bistatic operations without wired connections.

If you find this repository useful, please cite our paper:

Z. Zhou, C. Zhang, X. Xu, and Y. Zeng, "OpenISAC: An Open-Source Real-Time Experimentation Platform for OFDM-ISAC with Over-the-Air Synchronization," submitted to IEEE Trans. Wireless Commun., Jan. 2026.

[arXiv]

Affiliation

SEU Logo PML Logo

Yong Zeng Group at the National Mobile Communications Research Laboratory, Southeast University and the Purple Mountain Laboratories

Community

WeChat Official Account:

WeChat QR Code

What it is — and what it is not

What OpenISAC is

OpenISAC is a simple OFDM-based communication and sensing system designed for academic experiments and rapid algorithm validation. Its goal is to provide a clean, minimal, easy-to-modify OFDM platform so researchers can iterate quickly on PHY/sensing ideas without the overhead of a full standard-compliant stack.

Because it focuses on simplicity, OpenISAC typically requires less compute and can often run at higher sampling rates than more complex, feature-complete systems.

What OpenISAC is not

OpenISAC is not intended to be a standard-compliant implementation. It does not aim to comply with existing standards such as Wi-Fi or 5G NR.

It is also not meant to replace or compete with full-stack open-source standard implementations such as openwifi or OpenAirInterface. If your goal is interoperability, standards compliance, or a production-grade protocol stack, those projects are the right direction.

When to use it

When not to use it

Sensing Demo

Delay-Doppler Sensing

Real-time delay-Doppler map of a moving drone.

Clutter Rejection

Comparison of MTI clutter rejection filter ON and OFF.

Micro-Doppler Sensing

Micro-Doppler signatures of drone ascending and descending.

Communication Demo

Video Streaming

Real-time video streaming via ffmpeg over the ISAC link.

Hardware Requirements

Backend (C++)

To set up the complete system, you will need:

Connection Setup

BS Node: 1x Computer, 1x USRP (2 Antennas: 1 TX, 1 RX), OCXO.

UE Node: 1x Computer, 1x USRP (1 Antenna: RX), OCXO.

Interface

Frontend (Python)

Software Requirements

Backend (C++)

Operating System

Ubuntu 24.04 LTS

Dependencies & Installation

1. UHD (USRP Hardware Driver)

Follow the official Ettus guide. Tested on UHD v4.9.0.1.

2. Install Aff3ct
sudo apt-get install nlohmann-json3-dev
git clone https://github.com/aff3ct/aff3ct.git
cd aff3ct
git submodule update --init --recursive
mkdir build
cd build
cmake .. -G"Unix Makefiles" -DCMAKE_CXX_COMPILER="g++" -DCMAKE_BUILD_TYPE="Release" \
-DCMAKE_CXX_FLAGS="-funroll-loops -march=native" -DAFF3CT_COMPILE_EXE="OFF" \
-DAFF3CT_COMPILE_SHARED_LIB="ON" -DSPU_STACKTRACE="OFF" -DSPU_STACKTRACE_SEGFAULT="OFF" \
-DCMAKE_CXX_FLAGS="${CMAKE_CXX_FLAGS} -faligned-new"
make -j$(nproc)
sudo make install
3. Clone & Build OpenISAC
cd ~
git clone https://github.com/zhouzhiwen2000/OpenISAC.git
cd OpenISAC
mkdir build
cd build
cmake ..
make -j$(nproc)
4. Performance Tuning
cd ~/OpenISAC
chmod +x set_performance.bash
./set_performance.bash

Note: secure_boot needs to be turned off in your BIOS settings to enable RT_RUNTIME_SHARE functionality.

UHD Thread Priority Configuration

If you see [WARNING] [UHD] Failed to set desired affinity for thread, you need to enable real-time priority for your user.

sudo groupadd usrp
sudo usermod -aG usrp $USER

Then add the following line to /etc/security/limits.conf:

@usrp - rtprio 99

Log out and back in for changes to take effect.

5. CPU Isolation and Execution

To ensure stable real-time performance, isolate CPU cores for signal processing.

Step 1: Isolate System Cores

cd ~/OpenISAC
chmod +x isolate_cpus.bash
sudo ./isolate_cpus.bash

Step 2: Run Application on Isolated Cores

Use the script to launch your application on the isolated cores:

cd build
sudo ../isolate_cpus.bash run ./OFDMModulator

Note: Always use the wrapper script when CPU isolation is active.

Reset Configuration (Optional)

To restore the system to its default state (allowing all processes to use all cores):

sudo ./isolate_cpus.bash reset

Frontend (Python)

It is recommended to use a conda or venv environment with Python 3.13.

Install Dependencies

pip install -r requirements.txt

Note: ffmpeg is required for video streaming demonstrations.

Enable GPU Acceleration (Optional)

If an Nvidia GPU is available, install cupy-cuda12x to enable GPU acceleration:

pip install cupy-cuda12x

Typical Usage Example

1. Startup of the BS

sudo -s
cd build
# For X310:
sudo ../isolate_cpus.bash run ./OFDMModulator --args "addr=192.168.40.2, master_clock_rate=200e6, num_recv_frames=512, num_send_frames=512"

# For B210:
sudo ../isolate_cpus.bash run ./OFDMModulator --args "num_recv_frames=512, num_send_frames=512, send_frame_size=11520, recv_frame_size=11520" --wire-format-tx sc8

Add --default-ip=<your front end IP> if you are using a separate computer for the frontend.

2. Startup of the UE

sudo -s
cd build
# For X310:
sudo ../isolate_cpus.bash run ./OFDMDemodulator --args "addr=192.168.40.2, master_clock_rate=200e6, num_recv_frames=512, num_send_frames=512"

# For B210:
sudo ../isolate_cpus.bash run ./OFDMDemodulator --args "num_recv_frames=512, num_send_frames=512, send_frame_size=11520, recv_frame_size=11520"

Add --default-ip=<your front end IP> if you are using a separate computer for the frontend.

3. Stream video to the BS

ffmpeg -re -stream_loop -1 -fflags +genpts -i video.mp4 -an -c:v libx264 -x264-params keyint=5:min-keyint=1 -b:v 3000k -minrate 3000k -maxrate 3000k -bufsize 1M -f rtp -sdp_file video.sdp "rtp://<your IP of the BS>:50000"

If you are streaming locally, your IP of the BS can be set to 127.0.0.1.

4. Play video from the UE

Copy video.sdp to the video receiver, modify m=video 50000 RTP/AVP 96 to m=video 50001 RTP/AVP 96.

ffplay -protocol_whitelist file,rtp,udp -i video1.sdp

Note that this command should be run on the frontend.

5. Run monostatic frontend

python3 .\plot_sensing_microDoppler_CPP_MTI.py

6. Run bistatic frontend

python3 .\plot_bi_sensing_microDoppler_CPP_MTI.py

Arguments Table

OFDM Modulator

The OFDMModulator (BS Node) can be configured using the following command-line arguments:

Argument Default Value Description
--args addr=192.168.40.2, master_clock_rate=200e6, num_recv_frames=512, num_send_frames=512 USRP device arguments
--fft-size 1024 FFT size
--cp-length 128 Cyclic Prefix length
--sync-pos 1 Synchronization symbol position index
--sample-rate 50e6 Sample rate (Hz)
--bandwidth 50e6 Analog bandwidth (Hz)
--center-freq 2.4e9 Center frequency (Hz)
--tx-gain 20 Transmission gain (dB)
--rx-gain 30 Reception gain (dB)
--rx-channel 1 RX channel index on the USRP
--zc-root 29 Zadoff-Chu sequence root
--num-symbols 100 Number of OFDM symbols per frame
--clock-source external Clock source (internal or external)
--system-delay 63 System delay samples for alignment
--wire-format-tx sc16 USRP TX wire format (sc8 or sc16)
--wire-format-rx sc16 USRP RX wire format (sc8 or sc16)
--mod-udp-ip 0.0.0.0 IP to bind for incoming UDP data payload
--mod-udp-port 50000 Port to bind for incoming UDP data payload
--sensing-ip 127.0.0.1 Destination IP for sensing data
--sensing-port 8888 Destination port for sensing data
--default-ip 127.0.0.1 Default IP for all services
--cpu-cores 0,1,2,3,4,5 Comma-separated list of CPU cores to use

OFDM Demodulator

The OFDMDemodulator (UE Node) supports the following arguments:

Argument Default Value Description
--device-args num_recv_frames=512, num_send_frames=512, send_frame_size=11520, recv_frame_size=11520 USRP device arguments
--fft-size 1024 FFT size
--cp-length 128 Cyclic Prefix length
--center-freq 2.4e9 Center frequency (Hz)
--sample-rate 50e6 Sample rate (Hz)
--bandwidth 50e6 Analog bandwidth (Hz)
--rx-gain 60 Reception gain (dB)
--rx-channel 0 RX channel index
--sync-pos 1 Synchronization symbol position index
--sensing-ip 127.0.0.1 IP for sending sensing data
--sensing-port 8889 Port for sending sensing data
--control-port 9999 Port for receiving control commands
--channel-ip 127.0.0.1 IP for channel estimation output
--channel-port 12348 Port for channel estimation output
--pdf-ip 127.0.0.1 IP for raw power delay profile (PDF) data output
--pdf-port 12349 Port for raw power delay profile (PDF) data output
--constellation-ip 127.0.0.1 IP for constellation diagram data
--constellation-port 12346 Port for constellation diagram data
--freq-offset-ip 127.0.0.1 IP for frequency offset data
--freq-offset-port 12347 Port for frequency offset data
--udp-output-ip 127.0.0.1 Destination IP for decoded user data
--udp-output-port 50001 Destination port for decoded user data
--zc-root 29 Zadoff-Chu sequence root
--num-symbols 100 Number of symbols per frame
--sensing-symbol-num 100 Number of symbols used for sensing
--clock-source external Clock source (internal or external)
--software-sync true Enable software synchronization
--hardware-sync false Enable hardware synchronization
--hardware-sync-tty /dev/ttyUSB0 TTY device for hardware sync
--wire-format-rx sc16 USRP RX wire format
--default-ip 127.0.0.1 Default IP for all services
--cpu-cores 0,1,2,3,4,5 Comma-separated list of CPU cores to use