周报12.20-12.26
第一部分:文献阅读
一、文献概述
这篇文章主要贡献:
设计了一套发射机和接收机,以及可以提升系统速率的增强型标签。
解决了OFDMA反向散射系统中的相偏问题。
构建了硬件原型,以及一个用于估计功耗的b标签IC。(感兴趣)
系统达到了良好的性能。
存疑:tag通过不同的移频构成了OFDM符号,并行传输的话怎么如何保证每路信号对应每路载波而不会受其他的tag的影响呢。
系统实现的挑战:校准时钟偏移,定制的激励源信号,校准相位偏移。
校准时钟同步:发射器,标签和接收器之间的时钟偏移
定制的激励源信号:激励信号应该满足有效数据的强度大于preamble的强度,因为要保证反向散射符号的幅度与前导码的幅度相当,否则会由于噪声干扰而导致高误码率。
校准相位偏移:实际上也是难以做到完全同步导致的。
二、系统概述
系统实现的流程:用多个tag并发传输数据,将数据调制到不同频率的载波上。这些载波正交构成OFDM符号。
产生OFDM的流程
产生OFDM的流程:输入数据bit—>按照调制方式对比特进行分组—>星座映射—>子载波映射—>IFFT然后发出
注:相邻正交子载波的间距是0.3125Mhz
系统模型及发送帧的流程:
首先通过RTS-CTS机制保留Wifi信道,之后发射机传输特定的帧。帧主要包括三个部分。帧的第一部分包含用于发送端和接收端同步和 PHY Header的前导码;(PHY Header是干啥的) 第二部分是用 OOK 调制 CW 产生的,其中包含前导码,使tag和发送端同步,以及发往标签的控制信息;第三部分,连续波被标签广播和反向散射,导频子载波用于接收机与发射机校准相位和残余频偏。来自标签的反向散射符号与来自激励信号发射器的burst preamble和 PHY Header连接,在接收器形成一个完整的OFDM burst
三、系统实现的细节
- 发送机:产生连续波和OOK信号,分别用于rx-tx同步和rx-tag同步,用2进制控制,全1就是发CW波,有0有1就是发OOK信号。可以用空的子载波来发CW波。然后讨论了以下发送的幅值是多少时系统的性能最好,以及说明了IFFT会产生双边频谱,这样造成频谱浪费,可以用带通滤波器解决这个问题。然后还说明了双边带对反向散射的性能没有本质的影响。
- 标签:与Hitchhike相同的设计,也是先判断信号什么时候来,再通过产生方波进行移频做反向散射。但是增加了tx-to-tag 帧来进行tx和tag的同步。(就是OOK调制的那一部分)然后单边带的实现也和hitchhike一样,通过将信号分成两路,一路进行延时(频域上对应pi/2的移频,两路信号再进行叠加即可,这样可以实现主瓣上一个边带被抑制,旁瓣上可能没有抵消,但是可以不考虑)。
然后还设计了一个增强型标签来提升吞吐量。(没看懂,下面是原文翻译)
通过组合多个 SSB 模块来生成增强型 OFDMA 标签来提高数据速率。增强型 OFDMA 反向散射标签设计可以与模拟 OFDM 类似的方式实现,它将集中时钟分离到子模块。连续波是首先拆分为8条路径,每条路径为一组进行SSB调制,如图9所示。这样,增强标签可以分配4个子载波,理论上与常规标签比提供4倍的数据速率,在实践中可以应用于对带宽要求更高的设备。
增强型标签技术还有助于解决频率选择性衰落问题,通过多个子载波传递信息;(OFDM信号的子载波间距小,可以认为信号带宽小于相干带宽)理论上,可以增强标签,使其具有反射多个子载波的能力,但这会导致高功耗和大尺寸标签。
相干带宽约等于多径时延时间的倒数,。
接收机:发射机发送的前导码和标签的反向散射符号依次到达接收机,形成一个完整的 OFDM 脉冲串。 合成的burst然后由接收机处理,如图 10 所示。 来自 ADC 的 I/Q 流由常规模块依次处理,包括数据包检测、LTS 相关、同步、频率相关、CP 去除、FFT 和解映射,之后得到一个复数序列。反向散射引起的相位偏移由phase estimation解决。接收器中的另一个精简是绕过bitstream processing模块,如图 10 的右侧部分所示。该模块包括解交织、维特比解码和解扰的功能。
需要注意的是,发送端的的输入是用于产生激励信号的比特流;然而,接收端的输入是从标签反向散射数据。这种不一致使得维特比解码模块认为接收到的比特流已损坏,因此会对流进行校正,从而污染有效载荷数据并导致通信失败。因此,我们需要在接收器上绕过这个模块。(那怎么算误码率啊??)
对于问题3,也就是相位偏移校准的问题,此文献提出了三种分析方案:静态的偏移,连续的动态偏移和离散的动态偏移。
相位偏移的原因:延时的存在
静态的偏移主要是由于延时引起的。标签电路的延时,FFT加窗的延时传播延时等等,产生的影响就是星座图与正常的BPSK相比有一个旋转。
连续的动态偏移主要通过每次改变一点波形的相位产生的,最后的效果就是点沿单位圆连续移动。
离散的动态偏移是由标签产生的。通过改变tag产生方波的相位产生离散的动态频偏,影响效果就是点沿单位圆移动,但是有一定的步长。
这一部分的写作风格也值得学习。先摆出图,首先描述图里的现象是什么,然后描述不同的偏移具体代表什么,以及它是怎么实现的,这样行文逻辑很清晰。
功耗估计考虑到了移频的功耗,单边带电路部分的功耗。用到了time-to-digital converter,(时间数字转换器)differential ring oscillator (差分环形振荡器)等
四、测试
再之后就是测试部分,这篇文章测试了preamble和标签真正开始反射数据之间的时间差不同的误码率,吞吐量。子载波不同频偏的误码率,吞吐量。不同调制方式对应的误码率,吞吐量。视距,非视距的误码率,吞吐量,增强型标签的性能,以及和wifi backsactter做了个比较。
五、收获
通过读这篇文献,感觉通过OOK实现rx和tag之间的严格同步的思想值得学习,测试的内容值得参考,增强标签的部分不是很理解。
摘要——
在环境反向散射通信系统中,超低功率设备能够通过反向散射由 Wi-Fi 和蜂窝网络等传统通信系统生成的环境射频信号来传输信息。本文关注传统正交频分复用 (OFDM) 信号上的环境反向散射通信。我们提出了一种反向散射调制方案,它允许反向散射设备利用周围 OFDM 符号的频谱结构来传输信息。
所提出的调制方案允许使用非相干能量检测进行二进制和更高阶调制。我们研究了检测器设计并分析了所提出方案的错误性能。我们为二元情况提供了错误概率的精确表达式,而为 M 元情况导出了错误概率的准确近似表达式。 我们使用蒙特卡罗模拟证实了我们的分析,并研究了改变 OFDM 符号大小、最大信道延迟扩展和接收天线数量对错误性能的影响。我们的数值结果表明,所提出的技术优于本文中可用的其他技术,用于在不同场景下通过环境 OFDM 信号进行反向散射通信。
\本文的贡献**
• 我们提出了一种调制方案,用于利用带内空子载波的环境OFDM 载波上的反向散射通信。我们为二进制情况和检测器设计了标签调制波形,以避免直接链路干扰。
• 我们分析了所提出方案的错误性能,并根据二元Meijer G 函数获得平均错误概率的精确表达式。我们不使用高斯近似,我们的分析考虑了反向散射信道的级联衰落特性以及 OFDM 波形和宽带无线信道中固有的相关性。
• 为了提高错误性能,我们建议使用多个接收天线。特别是,我们建议使用非相干检测后等增益组合,在不了解信道实现或周围 OFDM 符号的情况下获得用于能量检测的复合测试统计数据。我们将错误分析扩展到多个接收天线的情况,并获得错误概率的精确表达式。
• 为了提高通信速率,基于将能量转移到空子载波的相同基本思想,我们提出了一种 M-ary 调制方案,允许每个 OFDM 符号传输多个比特,同时保留非相干检测的能力,仅依赖于能量检测。
• 最后,我们提供仿真结果来证实我们的分析并研究多个系统参数,即最大信道延迟扩展、OFDM 符号大小和接收天线数量对所提出的调制方案的错误性能的影响。
看了一下感觉看不懂,放弃了。
第二部分:一些grc模块的学习
一、学习了一些grc的模块的功能
Stream Mux模块
从第一个vector中获取3个元素,从第二个vector中获取两个元素,然后重复。下面这个例子就是1,2,3,4,5,6,7,8,9.
二、Gnuradio新建模块的初始代码分析
- 新建一个模块的.h文件: add_const_f_impl.h
代码分析:
(1) \初始分析**
gr是gnuradio的标准库,howto是自己建的工程名字,新建的模块名(GUI界面的框图名)为add_const_f。
(2) \namespace的作用**
在C++中,名称(name)可以是符号常量、变量、函数、结构、枚举、类和对象等等。工程越大,名称互相冲突性的可能性越大。另外使用多个厂商的类库时,也可能导致名称冲突。为了避免标识符的命名发生冲突,标准C++引入关键字namespace(命名空间/名字空间/名称空间),可以更好地控制标识符的作用域。
命名空间只能全局定义,不能定义局部定义,比如在某个函数中定义,命名空间可以嵌套。
用法为:
1 | namespace A { |
(3) \基类和派生类**
class add_const_f_impl : public add_const_f
add_const_f是基类,add_const_f_impl是派生类。add_const_f是自动生成的,在include目录中。
private中需要我们自己定义模块需要的变量,public首先定义了构造函数和析构函数,然后work函数主要用作信号处理。
- include文件夹下的add_const_f.h文件
(1) \#ifndef和#endif**
#ifndef(if not defined)如果没有定义这个函数,接下来就定义。
#endif 如果定义了这个.h文件,这个文件就不用定义了。
(2) \头文件**
引入了api和sync输入输出类型的两个头文件
(3) \typedef**
typedef给数据类型起别名,相当于给boost::shared_ptr
typedef好处就是可以更好的理解变量的含义,比如说:
typedef int age;给定int一个别名age
那么在定义时就能直接用age a = 13;代表13岁,这样更加直观,好区分。
(4) \智能指针**
boost::shared_ptr是智能指针,编译器可以判断什么时候释放内存,new完对象后不用delete。详细介绍如下:
(https://www.cnblogs.com/gadfly/archive/2010/09/27/1836992.html)
- 新建一个模块的.cc文件: add_const_f_impl.cc
)
(1) \#ifdef和#endif:**
一般情况下,源程序中所有的行都参加编译。但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是“条件编译”。有时,希望当满足某条件时对一组语句进行编译,而当条件不满足时则编译另一组语句。
(2) \构造函数**
构造函数调用了gnuradio的io_signature模块,包括模块的最小输入个数,最大输入个数,输入数据的数据类型,更多io_signature相关的资料可以参考下面的网址。
(https://blog.csdn.net/wh1312142954/article/details/80475627)
(3) \Work函数**
Work函数用作数据处理,有3个形参,其中noutput_items表示模块最大能处理的采样点数,后面两个表示两组数组。下面两行代码表示用const指针定义了两个变量并赋给其首地址,用作信号处理。
(4) \.h文件和.cc文件的关系**
.h文件和.cpp/.cc文件点的关系就是.h文件先声明一些变量,构造函数,析构函数,功能函数等,.cc文件包含.h文件,之后再展开说明每个函数都是干嘛用的。
(5) \unit8_t数据类型**
unit8_t:无符号一个字节的整型
三、**Wifi系统的学习和分析**
\1. 现有的系统和其效果
(1) \Wifi系统的流图:**
(2) \收到的数据:**
- 系统流图各个模块的分析
注意:Wifi流图中Wifi phy hier的时间间隔和接收端一致。
(1) \grc中实线和虚线的区别**
Gnuradio中数据流传输用实线表示,信息流传输用虚线表示。在block层面的代码中,流数据在work函数中处理,消息在消息处理函数中处理。(标签流和数据流并行处理)
首先,stream 在 GR 中作为需要处理的数据,在数字信号中就是一个个采样点的信息,GR 对 stream 数据的处理无法区分数据的性质,例如在一个滤波器模块中,会将真实数据和噪音一视同仁当作有效数据进行滤波操作,这时就无法辨别协议数据单元(PDU)与信号数据,所以就需要 message 数据进行其他信息的传输。
标签与数据流同步传输,消息流和数据流异步传输,传输协议数据单元。
(https://blog.csdn.net/Flag_ing/article/details/118019362)
(https://zhuanlan.zhihu.com/p/358657568)
(2) \消息传输机制与PMT数据类型**
实现消息机制主要依赖于PMT,也就是多态类型,pmt可以定义不同的数据类型,比如dict型,vector型等。感觉它的效果就类似与模板,定义一个pmt类型可以代表不同的数据类型,(int,char等等)
python中有pmt库,通过swig可以将这些变量传递给C++。
PMT类型的转换使用from_x,to_x机制
1 | pmt::pmt_t P_int = pmt::from_long(42); //long类型转换为pmt类 |
定义输入和输出接口以及其ID号
1 | void message_port_register_in(pmt::pmt_t port_id) //pmt::pmt_t是数据,port_id是端口号 |
如果其他的block要与这个block通信,就要subscribe这个端口
1 | void message_port_pub(pmt::pmt_t port_id,pmt::pmt_t msg);//感觉是公开端口的信息的意思 |
订阅完之后,需要一个函数来处理消息,把端口绑定到信息处理模块上,用boost库中的bind函数实现
1 | set_msg_handler(pmt::pmt_t port_id, |
(3) \Gnuradio的标签机制:**
流标签(Stream Tags)是为数据流中的特定 item(即数据项,数据项可以理解为一个数据单元,这个单元可以是一个向量、数组、一般的数据类型如 float、int、char 等类型的数据,一下简称数据)打上标签,用以标记我们认为的一些特殊的数据(比如幅值低于某个阈值的无效数据等),便于后续数据的处理。标签的形式是一个键值对(key:value pair),定义在块(block)的 work 函数中。其中键(key)指明了值(value)所代表的含义,值包含了这个标签里要传输的数据内容。键和值都是PMTs类型的数据,键是一个pmt symbol类型的数据,而值可以是任何数据类型的的pmt。另外,标签中还有一个额外的部分Src ID(源ID),也是pmt symbol类型的数据,指明了创建这个标签的块,一般是块的别名。
标签包含四个部分:偏置,键,值和源ID
(4) \Wifi框图中的一些变量及框图含义:**
变量:interval(发送包的时间间隔,单位为ms);pdu_length(包长);编码方式;信道估计方式
框图的作用:
Message Strobe:定义输入的数据和发送pdu的时间间隔。
Wifi MAC:定义源地址,目的地址和基本服务集地址?(BSS MAC是啥)
PDU to tagged stream:tag定义数据包的长度,按这个长度对数据进行分组。
QT GUI Constellation Sink: 画出信号的星座图。
Wifi Parse MAC:进行帧输出,linux命令行看到的输出全都是这个模块的。
Wifi PHY Hier模块:
消息从Wifi Mac模块传输到pad source模块,pad_source对应于mac_in接口,这部分是链路层。
Wifi mapper对数据添加服务域和填充比特,然后进行加扰,编码,多信道捆绑接入(puncturing),交织,下降到物理层。
- Packet Header Generator:没有.cc文件,只有.yml文件
感觉是将原始的数据流中提出一部分做包头。
Chunks to Symbols:输入是char数据类型,输出为gr_complex类型,此模块作用是对数据进行调制,包括bpsk,qpsk,16qam,64qam。
Tagged stream mux:两路带标签的流信号聚合。
OFDM Carrier Allocator:OFDM载波分配,包括fft长度,导频位置,数据位置,导频数据等等
OFDM Cyclic Prefixer:加循环前缀,16位。
Pad_sink连接samp_out端口再连接usrp_sink。
(这个模块中有两个Chunks to Symbols经过Tagged stream mux聚合而成,一路有产生了包头,一路没有产生包头,这部分没太看懂)
Delay:延迟的采样点数,具体对波形影响多少与采样频率关系很大。
Complex to Mag:复数求模值。
Complex to Mag^2:复数求模值再平方,输入是复数类型,输出是float类型。
Complex Conjugate:输出是输入的复共轭。
Moving average:求滑动平均,length是滑动窗口的大小,scale是缩放比例,max iter是最大迭代次数,输出的值和输入的值的关系是:
Output(i)(vector_index) = scale * sum(Input(i-length:i)(vector_index))
Divide:输入0/输入1
Wifi Sync Short:Wifi短同步
Wifi Sync Long:Wifi长同步
Stream to vector:从数据流到向量,串并转换
Wifi frame equalizer:得到FFT后的数据后进行子载波重排,信道估计和信道均衡。
Decode mac:解交织,viterbi译码,解扰。
只是粗略了看了一下每个模块的功能,一些实现的细节还没看。