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. 2025.
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. DPDK (Optional)
sudo apt update
sudo apt upgrade
sudo apt install dpdk dpdk-dev
Note: Install DPDK before building UHD if you plan to use it.
2. UHD (USRP Hardware Driver)
Follow the official Ettus guide. Tested on UHD v4.9.0.1.
3. 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
4. Clone & Build OpenISAC
cd ~
git clone https://github.com/zhouzhiwen2000/OpenISAC.git
cd OpenISAC
mkdir build
cd build
cmake ..
make -j$(nproc)
5. 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.
6. 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"
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 |