Skip to content

Latest commit

Β 

History

86 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

SDP: Sensing Data Protocol for Scalable Wireless Sensing

SDP Website PyPI License Python PyTorch Tests Docs Colab

Published and maintained by SDP8.org β€” the official platform for reproducible wireless sensing.


πŸ“– Citation

If you use SDP in your research, please cite:

@ARTICLE{11652923,
  author={Zhang, Di and Huang, Jiawei and Cui, Yuanhao and Cao, Xiaowen and Han, Tony Xiao and Jing, Xiaojun},
  journal={IEEE Transactions on Mobile Computing},
  title={SDP: A Unified Protocol and Benchmarking Framework for Reproducible Wi-Fi Sensing},
  year={2026},
  volume={},
  number={},
  pages={1-14},
  keywords={Wireless fidelity;Modeling;Frequency;Protocols;Training;Streams;Accuracy;Measurement;Tensors;Antennas;Benchmark;canonical representation;channel state information (CSI);integrated sensing and communications (ISAC);reproducibility;wireless sensing},
  doi={10.1109/TMC.2026.3723025}}


πŸ†• What's New in v0.5.2

  • Modular algorithm pipeline -- freely compose preprocessing steps with AlgorithmStep and execute_algorithm_steps()
  • Pluggable readers -- bring your own file-format reader via register_reader() and pipeline(..., reader=) (CLI --reader)
  • Per-dataset pipeline presets -- widar, gait, xrf55, elderAL, zte via --algorithm-preset
  • Compatibility & stability fixes -- clearer errors when an algorithm doesn't support a dataset, checkpoint always saved, Python 3.9 fix, XRF55 subset split fix

🎯 What is SDP?

SDP is a protocol-level abstraction and unified benchmark for reproducible wireless sensing.

⚠️ SDP is not a new neural network, but a standardized protocol that unifies CSI representations for fair comparison.

πŸ†š Why Choose WSDP?

Capability WSDP SenseFi (2023) CSIKit
Built-in Models 19 (MLPβ†’Mamba/GNN) 11 (MLPβ†’ViT) ❌
Preprocessing Algorithms 26+ (Wavelet, STC, etc.) ❌ Basic
Datasets 5 4 ❌
Pluggable Architecture βœ… Registry ❌ ❌
Protocol Abstraction βœ… Unique ❌ ❌
Training Pipeline βœ… βœ… ❌
CLI βœ… Full Basic βœ…

Verified from official GitHub repos on 2026-03-17.


🧠 Model Zoo (19 Models, Baseline β†’ SOTA)

Category Models Use Case
Baseline MLP, CNN1D, CNN2D, LSTM Quick experiments, comparisons
Mainstream ResNet1D, ResNet2D, BiLSTM+Attn, EfficientNet Production use
SOTA ViT, Mamba, GNN, CSIModel Cutting-edge research
Specialized THAT, CSITime, PA_CSI Task-specific architectures
Lightweight WiFlexFormer, AttentionGRU Efficient deployment
Cross-Domain EI, FewSense Domain adaptation & few-shot
from wsdp.models import create_model, list_models
model = create_model("ResNet1D", num_classes=10, input_shape=(20, 30, 3))

⚠️ Baseline Model Architecture Note

Baseline models (MLP, CNN1D, CNN2D, LSTM) use a Spatial Encoder (Conv2d-based) to compress the (F, A) antenna dimension before temporal processing. This prevents parameter explosion from direct (T, F, A) flattening. See CHANGELOG.md for details.


πŸ§ͺ Algorithm Library (26+ Algorithms in 7 Categories)

Category Algorithms Count
Denoising Wavelet, Butterworth, Savitzky-Golay, Bandpass, Hampel 5
Phase Calibration Linear, Polynomial, STC, Robust 4
Amplitude Z-Score, Min-Max, IQR Outlier, AGC Compensation 4
Interpolation Linear, Cubic, Nearest, Anti-alias Decimate 4
Features Doppler, Entropy, CSI Ratio, Tensor, Conjugate Multiply, PCA Fusion 6
Detection Variance, Change Point 2
Composition Pipeline presets, YAML config -
from wsdp.algorithms import denoise, calibrate, normalize
denoised = denoise(csi, method='butterworth', order=5, cutoff=0.3)
calibrated = calibrate(csi, method='stc')

See Model Guide and Algorithm Guide.


🎯 What is SDP? (Cont.)

The Problem

Wireless sensing research often suffers from:

  • ❌ Hardware-specific CSI formats
  • ❌ Inconsistent preprocessing pipelines
  • ❌ Unstable training results
  • ❌ Large performance variance across random seeds

Result: Models cannot be fairly compared.

The Solution

SDP solves this at the protocol level, not the model level:

Feature Raw CSI Other Tools SDP
Standardized Format ❌ Hardware-specific ⚠️ Partial βœ… Unified CSIFrame
Multi-Dataset Support ❌ Manual parsing ⚠️ 2-3 datasets βœ… 5 datasets built-in
Preprocessing ❌ DIY ⚠️ Basic only βœ… Wavelet + Phase Calib
Reproducibility ❌ Random ⚠️ Varies βœ… 5-seed standard
Deep Learning ❌ From scratch ⚠️ Limited βœ… CNN+Transformer
CLI Interface ❌ None ⚠️ Partial βœ… Full CLI support

SDP projects raw CSI into a fixed canonical frequency grid (K=30), ensuring cross-hardware comparability.

Performance Highlights

Metric Result
Accuracy SOTA on 5 datasets
Reproducibility 5-seed evaluation standard
Stability Low variance across runs

Accuracy Figure 1: Accuracy comparison across datasets

Reproducibility Figure 2: Reproducibility and stability analysis

Ablation Figure 3: Ablation study results


πŸš€ Quick Start (3 Steps, 5 Minutes)

Step 1: Install (30 seconds)

pip install wsdp

Verify installation:

wsdp --version

Step 2: Download Dataset (2 minutes)

πŸ”‘ Required: Create a free account at SDP8.org β€” your account credentials are needed for dataset downloads.

🌐 VPN is recommended for downloading datasets.

Option A: From CLI (Recommended for testing)

All datasets hosted on SDP8.org:

# elderAL = smallest dataset, fastest for testing
# Use your SDP8.org email/password:
wsdp download elderAL ./data --email you@example.com --password yourpassword

# Or use a JWT token (from SDP8.org dashboard):
wsdp download elderAL ./data --token YOUR_JWT_TOKEN

# Download larger datasets:
# wsdp download widar ./data
# wsdp download gait ./data
# wsdp download xrf55 ./data
# wsdp download zte ./data --email you@example.com --password yourpassword
# ⚠️ zte requires applying for access on the SDP platform first

Option B: From SDP8.org Web Interface

Log in at sdp8.org and download datasets manually.

Required Dataset Structure:

data/
β”œβ”€β”€ elderAL/                    # Dataset name
β”‚   β”œβ”€β”€ action0_static_new/     # Activity folder
β”‚   β”‚   β”œβ”€β”€ user0_position1_activity0/  # Sample folder
β”‚   β”‚   β”‚   β”œβ”€β”€ sample1.csv
β”‚   β”‚   β”‚   └── ...
β”‚   β”‚   └── ...
β”‚   β”œβ”€β”€ action1_walk_new/
β”‚   └── ...
β”œβ”€β”€ widar/
β”‚
β”œβ”€β”€ gait/
β”‚
β”œβ”€β”€ xrf55/
β”‚   └── WIFI/
β”‚       └── sample.npy
└── zte/

Step 3: Train & Evaluate (2 minutes)

🐍 Python API (Recommended for research):

Create train.py:

from wsdp import pipeline

# Minimal call - uses default hyperparameters
pipeline("./data/elderAL", "./output", "elderAL")

# Or with custom hyperparameters
pipeline(
    input_path="./data/elderAL",
    output_folder="./output",
    dataset="elderAL",
    learning_rate=1e-3,
    num_epochs=50,
    batch_size=64,
)

Run:

python train.py

πŸ’» CLI (Quick & Simple):

# Basic training
wsdp run ./data/elderAL ./output elderAL

# With hyperparameter override
wsdp run ./data/elderAL ./output elderAL --lr 0.001 --epochs 50 --batch-size 64

# With hyperparameter config file (YAML, top-level key = dataset name)
wsdp run ./data/elderAL ./output elderAL --config my_config.yaml

# Swap the model: a registered model name, or your own .py file
wsdp run ./data/elderAL ./output elderAL --model THAT
wsdp run ./data/elderAL ./output elderAL -m custom_model.py

# Custom preprocessing: algorithm config (YAML/JSON) or a preset
wsdp run ./data/elderAL ./output elderAL --algorithm-config my_algorithms.yaml
wsdp run ./data/elderAL ./output elderAL --algorithm-preset high_quality

πŸ“Š What You Get:

After training, check ./output/ (one set of files per random seed, 5 seeds by default):

output/
β”œβ”€β”€ best_checkpoint_<seed>.pth    # Best model checkpoint for each seed
β”œβ”€β”€ training_history_<seed>.csv   # Per-epoch loss & accuracy for each seed
└── cm_rs_<seed>.png              # Confusion matrix for each seed

Mean and variance of Top-1 accuracy across seeds are printed to the console at the end.

βœ… If you see these files, SDP is working correctly!


πŸ“Š Supported Datasets

Dataset Format Subcarriers Complex Scenarios Size
Widar .dat (bfee) 30 βœ… Gesture recognition ~2GB
Gait .dat (bfee, Intel IWL5300) 30 βœ… Gait recognition ~1GB
XRF55 .npy 30 βœ… Human activity ~3GB
ElderAL .csv varies ❌ Elderly activity ~500MB
ZTE .csv 512 βœ… CSI with I/Q ~4GB

More datasets coming soon!


πŸ”¬ Research & Customization

🧠 Plug in Your Own Model

Step 1: Create custom_model.py:

import torch
import torch.nn as nn

class YourCustomModel(nn.Module):
    def __init__(self, num_classes=6):
        super().__init__()
        # Your architecture here
        # Input shape: (Batch, Timestamp, Frequency, Antenna)
        
    def forward(self, x):
        # Your forward pass
        return output

# Required: expose model class
model = YourCustomModel

Step 2: Run with your model:

wsdp run ./data/elderAL ./output elderAL -m custom_model.py

πŸ“ Use Your Own Dataset

Labels and split groups are parsed from filenames, so name your files after one of the built-in dataset conventions (e.g. XRF55 user_action_trial) and pass that dataset name. If your files use a custom format, register a reader for it:

from wsdp import pipeline
from wsdp.readers import BaseReader, register_reader

class MyReader(BaseReader):
    def sniff(self, file_path): return file_path.endswith(".myfmt")
    def read_file(self, file_path): ...  # parse the file into CSIData

register_reader("my_format", MyReader)
# Filenames follow the XRF55 convention -> dataset="xrf55" + custom reader for the format
pipeline("./data/my_dataset", "./output", "xrf55", reader="my_format")

End-to-end example: examples/scripts/custom_reader_algorithm.py.

πŸ—ΊοΈ Codebase Map

Want to go deeper? Here's where to modify:

Directory Purpose What to Modify
models/ Architectures Define or compare model architectures
algorithms/ Signal Processing Denoising, calibration, etc.
datasets/ Dataset Wrappers Add new dataset loaders
readers/ File Readers Add new format parsers
structure/ Data Structures Modify CSIFrame format
processors/ Protocol Logic Adjust canonical projection

πŸ”Œ Pluggable Algorithm Architecture

WSDP features a Registry Pattern that makes algorithms pluggable:

from wsdp.algorithms import denoise, calibrate, register_algorithm

# Unified API β€” switch methods with one parameter
denoised = denoise(csi, method='butterworth', order=5)
calibrated = calibrate(csi, method='stc')

# Register your own algorithm
def my_denoise(csi, **kwargs):
    return my_custom_filter(csi)

register_algorithm('denoise', 'my_method', my_denoise)
result = denoise(csi, method='my_method')  # Works like built-in!

You can try this in examples/getting_started.ipynb or just in your custom pipeline!

Configuration file support:

# examples/configs/algorithms_config.yaml
denoise:
  method: butterworth
  params:
    order: 5
    cutoff: 0.3
calibrate:
  method: stc
normalize:
  method: z-score
from wsdp.algorithms import load_config, execute_pipeline
config = load_config('examples/configs/algorithms_config.yaml')
processed = execute_pipeline(csi, config)

Or:

pipeline(
    "./data/elderAL",
    "./output",
    "elderAL",
    algorithm_config_file='./examples/configs/algorithms_config.yaml',
)

Pipeline presets:

from wsdp.algorithms import apply_preset, execute_pipeline

# Choose a preset for your use case
steps = apply_preset('high_quality')  # or 'fast', 'robust', etc.
processed = execute_pipeline(csi, steps)

Modular pipeline (compose or skip steps freely):

from wsdp.algorithms import AlgorithmStep
from wsdp.processors import ModularProcessor

steps = [
    AlgorithmStep(category="denoise", method="wavelet", params={"level": 2}),
    AlgorithmStep(category="normalize", method="z-score"),  # calibration skipped
]
data, labels, groups = ModularProcessor(steps).process(csi_data_list, dataset="xrf55")

Config-file form: examples/configs/modular_pipeline.yaml.

πŸ“Š Algorithm Library

Category Algorithm Key Function Reference
Denoising Wavelet wavelet_denoise_csi() Donoho & Johnstone, 1994
Butterworth butterworth_denoise() Butterworth, 1930
Savitzky-Golay savgol_denoise() Savitzky & Golay, 1964
Bandpass bandpass_filter() Standard DSP
Hampel hampel_filter() Hampel, 1974
Phase Calibration Linear phase_calibration() Halperin et al., 2010
Polynomial polynomial_calibration() Extension of linear
STC stc_calibration() Xie et al., IEEE TWC 2019
Robust robust_phase_sanitization() Wang et al., ICPADS 2012
Normalization Z-Score normalize_amplitude() Standard statistical
Min-Max normalize_amplitude() Standard statistical
AGC Compensation agc_compensate() AGC gain correction
Interpolation Linear/Cubic/Nearest interpolate_grid() de Boor, 1978
Anti-alias Decimate decimate() Anti-alias downsampling
Features Doppler doppler_spectrum() Ali et al., MobiCom 2015
Entropy entropy_features() Shannon, 1948
CSI Ratio csi_ratio() Halperin et al., 2011
Tensor Decomposition tensor_decomposition() Kolda & Bader, SIAM 2009
Conjugate Multiply conjugate_multiply() Antenna pair correlation
PCA Fusion pca_fusion() Dimensionality reduction
Detection Activity detect_activity() Zhou et al., 2013
Change Point change_point_detection() Adams & MacKay, 2007

Built-in Presets:

Preset Denoise Calibrate Use Case
high_quality Butterworth (order=5) STC Maximum accuracy
fast Savitzky-Golay Linear Speed-optimized
robust Wavelet Robust Noisy environments
gesture_recognition Butterworth (order=4) STC Gesture tasks
activity_detection Savitzky-Golay Polynomial HAR tasks
localization Wavelet Robust Localization tasks

Per-dataset presets (widar, gait, xrf55, elderAL, zte) are also available; they currently mirror the legacy default chain (linear calibration

  • wavelet denoise).

πŸ§ͺ Understanding SDP (10-Min Deep Dive)

The SDP Pipeline

Raw CSI
  ↓
[Deterministic Sanitization]
  - Phase calibration
  - Wavelet denoising
  ↓
[Canonical Tensor Construction]
  - K=30 frequency grid
  - Standardized shape
  ↓
[Deep Learning Model]
  ↓
Prediction

Canonical Tensor Format

After sanitization, SDP constructs a Canonical CSI Tensor:

$$X \in \mathbb{C}^{A \times K \times T}$$

Where:

  • $A$ = Number of antennas
  • $K$ = 30 (fixed frequency grid)
  • $T$ = Time samples

This ensures cross-hardware comparability.

Why Deterministic?

Raw CSI contains hardware distortions:

  • Phase offsets
  • Sampling time offsets
  • Noise fluctuations

SDP enforces deterministic calibration and denoising, guaranteeing:

  • βœ… Same raw CSI β†’ Same cleaned tensor
  • βœ… Reproducibility is enforced, not optional

πŸ“š Documentation & Resources

πŸŽ“ Tutorials (Recommended Order)

# Resource What You'll Learn
1 Quickstart Notebook 5-min intro β€” registry exploration & processor customization
2 Getting Started Notebook Algorithm deep-dive β€” phase calibration & denoising with step-by-step visualizations
3 Full Tutorial Notebook Colab End-to-end workflow β€” install β†’ preprocess β†’ train β†’ evaluate β†’ CLI

πŸ“˜ User Guide

Resource Description
Installation Setup & environment configuration
Quickstart Guide First steps with WSDP
Algorithm Guide How to choose and chain preprocessing algorithms
Python API Programmatic usage in detail
CLI Reference Command-line interface usage
Configuration YAML config files & pipeline presets

πŸ“Š Reference

Resource Description
Full Documentation Site Complete MkDocs documentation
API Reference All public APIs
Dataset Overview Format details & download guide for all 5 datasets
Model Guide All 19 models with architecture details
Leaderboard Benchmark comparison across models & datasets
Changelog Version history
Contributing Development guide & PR process

πŸ—ΊοΈ Roadmap

  • v0.1 - Initial protocol design
  • v0.2 - 5 datasets support, CLI tool
  • v0.3 - More datasets (WiFi-HAR, CSI-HAR, etc.)
  • v0.4 - 19 models, 26+ algorithms, leaderboard, CI/CD, scientific bug fixes
  • v0.5 - PyPI official release, online demo platform
  • v1.0 - Full protocol standardization

Want a specific dataset? Open an issue and let us know!


🀝 Contributing

We welcome contributions! See CONTRIBUTING.md for:

  • Development setup
  • Coding guidelines
  • Pull request process

πŸ“„ License

MIT License - see LICENSE file.


Made with ❀️ by the WSDP Team

⬆ Back to Top

About

A protocol-level abstraction and unified benchmark for scalable wireless sensing. SDP enforces deterministic physical-layer sanitization, canonical tensor construction, and standardized training and evaluation procedures, decoupling learning performance from hardware-specific artifac

Topics

Resources

Contributing

Stars

11 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages