基于CSI的移动目标侦测研究学习

Author Avatar
Xin Qiu Mar 12, 2016
  • Read this article on other device

最近被老师带着搞科研,研究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

参考论文

  1. PADS Passive Detection of Moving Targets with Dynamic Speed using PHY Layer Information