基于CSI的移动目标侦测研究学习
最近被老师带着搞科研,研究CSI(channel state information)。
环境安装
需要用到CSI tool,这是一个运行在Ubuntu上的利用Intel Wi-Fi Wireless Link 5300 802.11n来做分析的程序。这里可以使用作者网站中方法来安装,也可以下载清华的版本。清华的版本附带了安装说明书,参考说明书上的方法,安装即可。
需要注意的是,发射源路由器需要选择单天线支持802.11n的路由器,我使用的是TP-LINK TL-WR742N。
获取数据
cd进入csitools文件夹,进入linux-80211n-csitool-supplementary/netlink,运行
sudo ./log_to_file tmp.dat
打开另一个终端,运行
ping 192.168.1.1 -i 0.2
netlink文件夹中的tmp.dat就是采集的原始数据。
读取数据
使用Matlab读取数据,进入linux-80211n-csitool-supplementary/matlab文件夹,使用read_bf_file函数可以读取数据。
一个例子数据包里包含
timestamp_low: 4 (In the sample trace, timestamp_low is invalid and always 4.)
bfee_count: 72
Nrx: 3
Ntx: 1
rssi_a: 33
rssi_b: 37
rssi_c: 41
noise: -127
agc: 38
perm: [3 2 1]
rate: 256
csi: [1x3x30 double]
其中:
- timestamp_low 是时间戳
- bfee_count 数据包数量
- Nrx,Ntx 分别表示接收端和发送端的天线数量
- rssi_a, rssi_b, rssi_c 每个天线的RSSI数据,单位dB,
- agc Automatic Gain Control
- perm NIC重排列后的顺序结果,代表RF链路的顺序
- rate 发送包的rate
- csi CSI原始数据,是个Ntx×Nrx×30复数矩阵
主要提取出CSI数据和timestamp_low。
数据预处理
为了避免相位的偏移的影响,需要将相位进行线性变换,参考论文,写出了以下Python代码:
from math import *
import numpy as np
import copy
N = 1000 # N为采集的数据包数量
def complexDecoding(raw_data):
"""
将原始数据转化为Python可识别的复数
这里使用了第一个天线的数据raw_data[0]
第二根第三根天线数据下标分别为1, 2
原始数据为a + bi, python为a + bj
返回处理后的数据
"""
for n in range(N):
for i in range(30): # 30 代表子载波数量,固定为30
if raw_data[0][-1] == 'i':
data.append(complex(raw_data[0][:-1]+'j'))
else:
data.append(complex(raw_data[0]))
return data
def getAP(data):
"""
根据复数计算振幅和相位
"""
amplitudes = [([] * 30) for i in range(N)]
phases = [([] * 30) for i in range(N)]
for m in range(N):
for i in range(30):
r = sqrt((data[i + m * 30].real) ** 2 + (data[i + m * 30].imag) ** 2)
amplitudes[m].append(r)
phases[m].append(np.angle(data[i + m * 30]))
return (amplitudes, phases)
def preprocessingPhase(phases):
"""
将相位进行线性变换
index是 -28 到 28 根据 IEEE 802.11n 协议
返回变换后的相位
"""
index = range(-28,0,2) + [-1, 1] + range(3,28, 2) + [28]
for m in range(N):
for l in range(10):
clear = True
base = 0
tphases[m][0] = phases[m][0]
for i in range(1, 30):
if phases[m][i] - phases[m][i-1] > pi:
base += 1
clear = False
elif phases[m][i] - phases[m][i-1] < -pi:
base -= 1
clear = False
tphases[m][i] = phases[m][i] - 2 * pi * base
if clear == True:
break
else:
for i in range(30):
phases[m][i] = tphases[m][i] - (tphases[m][29] - tphases[m][0])
* 1.0 /(28 - (-28)) * (index[i])
- 1.0 / 30 * sum([tphases[m][j] for j in range(30)])
return phases
参考论文
- PADS Passive Detection of Moving Targets with Dynamic Speed using PHY Layer Information