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
Yong Zeng Group at the National Mobile Communications Research Laboratory, Southeast University and the Purple Mountain Laboratories
Community
WeChat Official Account:
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
- Prototyping and testing new OFDM/ISAC algorithms
- Fast “idea → experiment” cycles with a minimal PHY
- Research setups where interoperability is not required
When not to use it
- Building a Wi-Fi/NR-compatible system
- Needing real-world standard features (full MAC/stack behavior, interoperability, certification-oriented behavior, etc.)
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:
- USRP Devices: 2 units (e.g., USRP X310, B210)
- Computers: 2 units (High performance recommended)
- Antennas: 3 total
- OCXO: 2 units (Required for both USRPs)
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
- >= 10 Gigabit Ethernet (10GbE) for X-series
- USB 3.0 for B-series
Frontend (Python)
- Computer: 1x Computer (Windows or Linux). Can be one of the backend computers or a separate machine.
- CPU: High performance CPU (i7 10700 or better) if no GPU is available.
- GPU: A Nvidia GPU is recommended for acceleration.
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.
- Ubuntu:
sudo apt install ffmpeg - Windows: Download from ffmpeg.org and add to PATH, or place executable in the working directory.
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 |