数据包,子载波关系
采集到的数据中包含了三根天线的CSI数据
dat-多个数据包-1个数据包包含3根天线对应的30个子载波的幅度
一个数据包含3根天线的数据,每根天线又包含56个子载波的瞬时值(数据包作为横轴,即时间作为横轴)
显然GitHub上是有数据处理的过程的,只是自己限定词范围问题
CSI WiFi
要相信百度上一定有你需要的code,只是你自己没有找到而已(找别人要是不现实的)
打开别人的工程文件时,直接shift,打开所有的.m文件,不要打开一两个,这样很容易出错
获取相位差数据设备的调研:
umain
UWB-Radar108R (呼吸监测) 呼吸监测UWB雷达模块组
http://www.umain.co.kr/zh-hans/shop/uwb-radar108r/
HST-D3 Evaluation Kit Raspberry Pi 3联动型雷达传感器应用开发Kit
http://www.umain.co.kr/zh-hans/shop/hst-d3/
NOVELDA
RESPIRATION SENSOR X4M200 呼吸检测
https://www.xethru.com/x4m200-respiration-sensor.html
CUSTOM SENSOR DEVELOPMENT X4M03 | X4M06 自行拓展开发
https://www.xethru.com/xethru-development-platform.html
目的:
原有程序怎么跑通?
先检测出静止,起身站立,行走三个状态(时间-幅度图画出来,幅度信息仅仅能反映出人体是否处于静止或非静止),自己画出来的图像应该是一条直线
分两种情况:视距和非视距(对比一下两者效果)
评价呼吸和心率的指标:
每分钟多少次:The breathing frequency of a normal adult is 12 to 20 times per min in a resting state [5], and the heart rate is 60 to 100 beats per min [6]。
频率:breathing from 0.2 Hz to 0.33 Hz [5] and heartbeat cycles from 1 Hz to 1.33 Hz [6](频率已知,可以通过滤波器提取出有用的信号)
bpm:breathing rate ranges from 10 to 37 bpm [18, 19], and heart rate ranges from 60 to 80 bpm [20]
CSI的值包含了子载波的信号强度和相位信息(数据包,子载波,CSI关系?),若环境中存在人活着人的运动,这会影响到WIFI信号的传播路径,所有子载波的CSI值都会被影响
延迟发生在LOS的信号和NLOS的信号上,LOS的信号线到大接收器
数据处理的一些方法:
1、跌倒检测论文
falldefi_example.m是主文件,应该是直接运行此文件
添加CSI工具的路径
添加跌倒检测脚本的路径
添加SVM的路径(做到上一步即可)
使用线性插值将.dat文件中的CSI提取到.mat
2、通过CSI信号检测心率和呼吸论文
①CSI的处理
对接收信号进行IFFT(傅里叶逆变换):得到近似的时域功率延迟曲线
去掉时域较小的信号分量
将剩下的时域信号再进行FFT变换
②过滤(breathing from 0.2 Hz to 0.33 Hz [5] and heartbeat cycles from 1 Hz to 1.33 Hz [6])
需要移除身体移动产生的影响和高频噪声,通过滤波器滤波后得到如下图的结果
③子载波选择
每一个子载波对于呼吸和心跳都有不同的敏感程度。如果用到所有的子载波,计算成本会很高
相邻子载波的近似的CSI值
选择的方法:通过一个时间窗口计算CSI幅度的方差,用于量化那些子载波对运动比较敏感。选择方差较大的子载波,方差越大对呼吸和心跳产生的微小运动才能越敏感
④分割(这个步骤不是很明白)
3、WI-sleep(这个才叫真正的论文,用的每一个方法都解释了为什么不用其他方法,大多数论文都只是说了用这个方法,没有说为什么用这个方法)
直接选择了天线1的第10个载波
跌倒检测中的坐在椅子上的数据和行走的数据差别很大
Python处理数据:
所有py文件放在一个文件夹下,直接打开文件夹,不能单个单个打开文件(不想C#中打开一个工程链接文件就能打开整个工程)
需要安装h5py模块,在win+r-cmd下执行
pip install cython
pip install h5py
再在pycharm中添加h5py的包
MATLAB处理数据:
csi_trace = read_bf_file('sample_data/walk_LoS.dat');
for i=1:200%这里是取的数据包的个数
csi_entry = csi_trace{i};
csi = get_scaled_csi(csi_entry); %提取csi矩阵
csi =csi(1,:,:);
csi1=abs(squeeze(csi).'); %提取幅值(降维+转置)
%只取一根天线的数据
first_ant_csi(:,i)=csi1(:,1); %直接取第一列数据(不需要for循环取)
second_ant_csi(:,i)=csi1(:,2)
third_ant_csi(:,i)=csi1(:,3)
% for j=1:30
% csi15_end(i,:)=csi1(j,:); %3个信道第j个子载波
% end
end
%画第一根天线的载波
%plot(first_ant_csi.')
plot(second_ant_csi.')
%plot(third_ant_csi.')
直接获取CSI数据的幅度,csi1=abs(squeeze(csi).'),csi是1×3×30的复数矩阵,取绝对值后得到CSI的幅度
200个数据包中第二根天线对应的第一个子载波的CSI取值范围,做一条垂线有200个交点(这个是没有转置的结果,没有什么意义)
转置后,每一个波形就表示每一个子载波随数据包/时间的的变化波形
行走
静坐
到此CSI随时间变化的幅度值获取到(这里横轴的间隔是有发送设备决定的,在发包时输入了发包间隔时间)
然后就是去掉异常值(试验数据中好像没有异常点):利用Hampel identifier去除异常点,离开封闭区间的点就当做异常点处理,μ表示一个波形的中位数,σ表示一个波形的the median
absolute deviation (MAD)(不同这个含义),γ一般取默认值3
疑问:异常点移除后加入的是什么值(看网上怎么实现的)
不选均值和标准差的原因:
插值(Interpolation):不能保证接收端数据包不丢失,因此必须插值(linear interpolation)
去噪:用的小波变换
子载波选择:选择更加具有周期性的波形。用的什么方法没有看懂
matlab程序:
数据实时可视化:https://blog.csdn.net/u014645508/article/details/82887470?utm_source=blogxgwz2(ubantu系统下实时画第一个图)
NIC5300的三个天线使用相同的时钟和相同的下变频器频率
来自两根天线的子载波i的相位有相同的包检测延迟,采样周期和频率差异(这也是处理数据的重要方法,直接计算两根天线上子载波的相位差)
相位差数据的图像是周期性的正弦波
相位可以理解成角度
人体活动早成信道失真和相位偏移
频域内的信道模型:
WiFi心率检测系统应包括下面四个模块:
数据提取,数据预处理,呼吸率估计和心率估计
现成的WiFi设备提取两个接收天线之间的CSI相位差数据
1、环境检测:用于检测人的状态(sitting、walking、standing up),大的运动会导致比呼吸和心跳更大的csi方差,通过设置一个阈值,就可以检测到较大的动作。当信号范围内没有人时,相位差数据是一条非常小的波动。当这个人站起来或正在走路的时候,相位差数据表现出较大的波动(用于检测物体是否移动)
论文中通过信号的幅度变化实现运动静止检测(论文后面也是使用相位差来做的),这里使用相位差来检测(首选方法)
randomly distributed raw phase can be calibrated by conducting phase difference over a pair of antennas(通过一对天线的相位差)
下图怎么画出来
相位差的计算方法:
2、数据校准:去除直流分量和高频噪声。直流分量影响子载波选择,峰值检测和FFT频率估计
防跌倒检测中用到相位校准
时延,子载波频率偏移
3、子载波选择:并不是所有的载波都会用到
4、离散小波变换(DWT):be decomposed into an approximation coefficients vector with a low-pass filter and a detail coefficients vector with a high-pass filter
- the approximation coefficient vector : the basic shape of the input signal with large scale characteristics
- detail coefficient vector :describes the high frequency noises and the detailed information with small scale characteristics
5、
level4的近似系数:用于获取去噪的呼吸信号
细节系数:用于重建心率信号
单人使用峰值检测
多人使用root-MUSIC method
专业术语:
相位:在函数y=Acos(ωx+φ)中,ωx+φ称为相位(通过圆上一点的移动画出正弦波形,此时对应的角度即为相角)
工具:
win10 MATLAB(linux安装MATLAB:https://blog.csdn.net/guituo9698/article/details/70553521)
相位差直接用设备检测出来的(没有手动处理得到)
文件:
ubantu系统下的matlab文件夹
CSI数据包:在inject文件夹中的那个,不是netlink中的
处理过程:
参考官网链接:https://dhalperi.github.io/linux-80211n-csitool/faq.html
https://blog.csdn.net/sinat_22991367/article/details/78187440
提示如下错误:
①这样当然会出错,read_bf_file函数不存在。
②这里的路径也存在问题(应该将编写的.m文件保存在matlab目录下)
解决方法:
read_bf_file.m文件在安装的ubantu系统下的MATLAB文件夹的中(但是自己安装的系统MATLAB文件夹下没有这些文件),将ubantu系统中的MATLAB文件夹移至windows系统中
将编写的读数据文件路径也保存在此目录下,如上图的show_csi.m文件
csi_trace = read_bf_file('sample_data/10_25.dat');
这里一定要注意程序中的调用路径,自己将数据放在matlab的sample_data目录下,在程序中sample_data不能少
csi_trace = read_bf_file('sample_data/10_25.dat');
csi_entry=csi_trace{1}; %只取了一个包的数据
csi = get_scaled_csi(csi_entry); %将数据包中的CSI数据单独取出
subplot(1,2,1)
plot(db(abs(squeeze(csi).'))) %降维成30×3的矩阵
legend('RX Antenna A', 'RX Antenna B', 'RX Antenna C', 'Location', 'SouthEast' ); %因此此处的横坐标表示的子波索引,纵轴表示此数据包中,子波的幅度
xlabel('Subcarrier index');
ylabel('SNR [dB]');
5300网卡有三个天线,三个线段代表三个接收天线的csi数据。如果你要简化计算,可以只取用第一个天线的数据,很多论文是这样处理。为了保证更高的精确性,三个天线的数据也可以都使用。(更复杂的情况是多发射天线多接收天线,就不止3个线段了,你会遇到ntx为2或3的情况,ntx为发射天线的个数,nrx为接收天线的个数)
实验结果:
直接从dat文件读取出来的是很多数据包,每个数据包的格式的格式如下:
timestamp_low:NIC网卡1MHz时钟的低32位。它大约4300s(72min)重复一回。 (从0-2^32需要4300s)
bfee_count:驱动记录并发送到用户控件的波束测量值的总数。内核和用户空间中netlink频道是有损的,可以用该变量来检测被丢弃的测量值。
Nrx:接收端使用的天线数量。
Ntx:发送端使用的天线数量。
rssi_a, rssi_b, rssi_c:由接收端NIC测量出的RSSI值。
perm:展示NIC如何将3个接收天线的信号排列到3个RF链上,上图中的数据表示天线A被发送到RF链A,天线B被发送到RF链B,天线C被发送到RF链C。
rate:发包频率。
csi:CSI值
此图对应一个数据包的图像,横轴表示子载波索引,纵轴表示这一个数据包中子载波的幅度
%实际情况时域柱状图
csi_trace = read_bf_file('sample_data/10_25.dat');
for l=1:100 %取50个数据包的数据
csia=get_scaled_csi(csi_trace{l});
for k=1:30 %30个子载波数据
B(1,1,k)=csia(1,1,k);%只是取了csia每行数据的前两个
end
csi_one=squeeze(B).';
for ki=1:30 %30个子载波数据
csi_amp(ki,l)=csi_one(ki); %第l个数据包的第k个子载波的幅度 【子载波,数据包】
end
end
csi_ifft=ifft(csi_amp(:,1));
T_amp=abs(csi_ifft);
bar(T_amp);
set(gca,'XTick',[0 10 20 30]);
set(gca,'xticklabel',{'0','0.5','1','1.5'});
xlabel('Delay (ms)');
ylabel('Amplitude(dB)');
csia_trace:实验只取了前100个数据包进行处理,每个包含有的数据如上
通过get_scaled_csi函数处理,csia_trace得到caia,30行(30个子载波),每行3个数据
再从每个子载波中选出第一个数据,得到B,30行,每行一个数据(这个数据就包含了CSI的幅度和相位信息)
通过squeeze函数,将B转化为1行30列的数据
最终得到50个数据包的30个载波的相位值(30行对应30个子载波,50列对应50个数据包)
子载波相位值通过FFT逆变换得到时域柱状图,纵轴表示信号的幅度,怎么画成曲线图并且画出更多的数据包?
这里应该是每个子载波的幅度值(每个子载波都是周期信号吗?),应该求出所有载波的幅度?
这里的横纵应该是Subcarrier index(?)
应该画出下面的图形(每个子载波随时间的变化)
相位图
实验结果和博客上的相差很大
CSI的跌倒检测:
数据处理参考链接:https://github.com/dmsp123/FallDeFi