20201201更新内容:

1.调整代码结构。wifilib.py提供两个常用的matlab函数read_bf_file()和get_scale_csi(),与matlab的功能保持一致,方便python调用
2.优化程序性能。提高了解析速度
3.新增了示例代码,demo.py

前言

数据采集工具csi_tool采集数据并保存为后缀.dat的数据文件,在csi_tool中提供一个c语言函数解析此文件。阅读了c语言的解析代码后发现,数据文件的组织方法与计网中数据十分相似,但略有不同。

数据格式

总体上,整个文件仅由n个bfee组成,巧了,数据文件中应当包含有n个采样信息,这个bfee的意义不言而喻,就是和采样一一对应。

bfee: 在这里插入图片描述

bfee的数据结构如上图所示。
前两字节是field_len,之后一字节是code,再之后便是可变长度的field。field_len等于code+field的字长。
当code为187时,表示field中是信道信息;不是187时,表示field中是其他信息。
我们关心的是信道信息,其他信息不解析,跳过该bfee即可。

field: 在这里插入图片描述

若code等于187,field有如上图数据格式。
到这里你一定感觉很熟悉了。 field分为头部和有效载荷(payload)两部分。头部有20字节的固定长度,有效载荷是个可变长度,字长为len。
头部各字段的数据类型和意义如下表:

在这里插入图片描述

可以见得,头部中包含了主要的信道信息。
而其中最重要的csi矩阵,分为30个subc,保存在有效载荷中。
分别对应30个子载波。

subc的结构如下表所示:

在这里插入图片描述

复数的结构:

在这里插入图片描述

每个subc的开始会有3位的非数据部分,因此subc的长度不是字节(8位)的整数倍,这将导致subc这部分的解析需要按比特操作,增加我解析工作的复杂度。

到这里,整个文件的数据结构都清楚了,开始试着用python来解析run-lxx.dat这个文件。 (真想交给王福超来写啊zzz)

文件解析

示例 demo.py:

import matplotlib.pyplot as plt
from wifilib import *

path = r"./run_lh_1.dat"

bf = read_bf_file(path)
csi_list = list(map(get_scale_csi,bf))
csi_np = (np.array(csi_list))
csi_amp = np.abs(csi_np)

print("csi shape: ",csi_np.shape)
fig = plt.figure()
plt.plot(csi_amp[:,0,0,3])
plt.show()

demo示例的解析结果:
avatar

matlab的解析结果:
avatar

其他和总结

正确的matlab解析步骤应该是:
1.从文件将头部信息和csi矩阵读取到字典,即read_bfee_file()
2.依次从字典中取出标准化CSI,即get_scale_csi()
3.将所有csi整合到一起,保存为csv