跳转至

数据包检测与同步

在无线信号通信和感知的应用中,接收设备往往需要准确地检测和提取发送端发送的信号,以正确地解码信息。这一过程称为发送端和接收端的时间同步。但是由于在无线通信和感知的场景中,发送端和接收端往往没有预先进行时间同步,需要利用发送的信号实现时间同步的功能。实现时间同步的信号被称作前导码(Preamble)。

前导码

前导码的定义与性质

在计算机网络中,前导码是一种信号,用于在计算机系统之间同步数据传输,确保接收端能够正确对齐并识别数据包。

前导码对于维持网络设备间的高效通信至关重要,其关键功能包括

  • 同步:确保网络系统之间的数据包正确对齐。
  • 识别:帮助接收端识别数据包。
  • 信道状态检测:通过已知信号检测信道的状态和特征。

前导码需要具有良好的时间性质,以实现精确的时间同步,该性质被称为自相关性质。

为了更好地理解自相关性质,我们首先介绍信号的自相关函数:

假设有一个离散时间信号为x[n],则其自相关函数为

R_{xx}[m] = E(x[m+n]x[n])
其中E( )表示数学期望。

该函数的意义为计算信号片段的相关程度。

我们使用一个动图展示了自相关函数的计算过程:

plt

对于自相关函数,当m=0时,该函数取得最大值,可以用于表示信号对齐。因此,自相关函数可以用于实现时间同步。

为了实现更精确的时间同步,前导码应当具有以下的性质:

  • 当前导码信号对齐(m=0)时,自相关函数有最大值。
  • 当前导码信号未对齐(m≠0)时,自相关函数接近于0。

利用前导码实现时间同步

利用前导码信号x[n]和接收信号y[n],计算二者的互相关函数,可以实现时间同步。互相关函数的定义为

R_{xy}[m] = E(x[m+n]y[n])
利用前导码信号良好的自相关性质,当前导码信号和接收信号时间对齐时,互相关函数有最大值。因此,互相关函数取得最大值的时间即为信号到达的时间。

前导码的设计

已有的研究对于前导码的设计有充分的研究。在这一部分,我们选取一些典型的前导码信号进行介绍。

需要注意的是,前导码信号针对二进制序列设计的信号与针对连续函数设计的信号,在这里我们介绍针对连续函数设计的信号。

伪随机信号

一种最简单的可用于前导码的信号为伪随机信号,利用随机函数生成一个序列。

N = 128;
signal = rand(1,N)*2-1;

其自相关函数图像如下:

autocorr_rand

可以看出伪随机信号具有良好的自相关性质,可以用作前导码。

但是使用随机函数生成的伪随机信号没有规律。现有的研究总结了很多伪随机信号用作前导码,我们介绍其中一种,Zadoff-Chu序列(ZC序列)。

ZC序列为一复数伪随机序列,其表达式为:

ZC[n] = exp(j\pi(\frac{un(n+c_f+2q)}{N}))
其中N为序列长度,u和n大于等于0且小于N,且u与N互质,c_f = N\%2,q为正数。

我们可以取该信号的实部作为前导码信号

\Re(ZC[n]) = cos(\pi(\frac{un(n+c_f+2q)}{N}))
该信号的自相关函数如下图:

autocorr_zc

该函数也可作为前导码的信号,且更容易生成。

伪随机信号虽然具有较好的自相关性质,如果对其进行频谱分析可以发现这些信号的频谱充满整个频带,在应用中,可能需要限制前导码信号的带宽,以避免产生噪音或干扰其他频带的信号,在这种情况下,需要设计带宽有限的前导码信号。

线性调频信号

线性调频信号,也可以称为chirp信号,其特性是频率随时间线性变化,可以表达为:

x(t) = cos(2\pi( f_{\min}t + \frac{1}{2}\frac{B}{T}t^2))
其中fmin为信号的最小频率,B为带宽,T​为信号的时间长度。

我们给出计算线性调频信号的自相关函数的计算代码:

%% 生成信号
N= 500; fs = 20000;
t = 0:1/fs:(N-1)/fs;
fmin = 100; fmax = 500; B = fmax-fmin;
T = N/fs;
signal = cos(2*pi*(fmin*t+0.5*(B/T)*t.^2));

%% 求自相关函数
% 滞后值(m)
lags = -(N-1):(N-1);
autocorr = zeros(1,2*N-1);
for m = lags
    if m<0
         autocorr(m+N) = sum(signal(1:N+m).*signal(-m+1:N))/N;
    else
         autocorr(m+N) = sum(signal(m+1:N).*signal(1:N-m))/N;
    end
end

% 绘图
plot(lags,autocorr,'lineWidth',1.5)

得出其自相关函数图像为:

chirp_corr

可以看出在有限的带宽下,线性调频信号有良好的自相关性质,能够作为前导码参与无线通信和感知。

[!TIP]

思考:在实际场景中,若存在频率偏移、相位偏移或多径效应,前导码信号及互相关函数有何变化?

调制方法综合应用

​ 以上介绍的幅度调制、频率调制和相位调制是调制方法中最基本的三类,将其中的一类进行改进,或者结合这3类方式,就可以发展出效率更高、抗噪声能力更强的调制方式。本节将介绍在三类基本调制方法上演变出的其他调制方式,包括脉冲间隔调制,OQPSK,QAM和OFDM。

脉冲间隔调制

​ 脉冲间隔调制是利用相邻两个脉冲信号之间的时间间隔来调制数据。使用指定长度的间隔来代表特定的二进制串。最简单的脉冲调制是使用一长一短两种间隔,分别代表“0”和“1”。在解码时,只需要识别出每个脉冲信号的起始位置,就可以得到不同脉冲之间的间隔,从而可以根据每个间隔的长短将其解码为“0”或“1”。

图. 脉冲调制原理

​ 脉冲间隔调制由于使用简单的对应规则将“0”和“1”编码为不同长度的间隔,在解码时可以根据信号幅度得到每个脉冲的起始位置来获得间隔的长短,这种编解码方法的优点是计算开销非常小。

脉冲间隔调制的缺点是编码效率低,每个脉冲之间需要有足够的时间宽度。

思考为什么要留足够的时间宽度。

留足够多的时间宽度可以来防止多径效应造成的回声影响到下一个脉冲的判断。想要提高脉冲调制的数据速率,可以从两个方面来考虑。

​第一个方面是缩短编码的长度,既可以缩短脉冲之间的时间间隔,也可以缩短脉冲信号本身的持续时间。在保证解码正确率的条件下,相同的时间就可以传输更多的数据。

图. 缩短脉冲间隔和脉冲持续时间可以提高编码效率

​ 第二个方面,可以通过设置多种编码长度,使一个编码位携带更多的信息。如下图中所示,设置2种编码长度时,每个编码位携带1比特信息;设置4中编码长度时,每个编码位携带2比特信息;设置8种编码长度时,每个编码位携带3比特信息。

图. 设置多种编码长度

当然,我们不能无限制地增加编码长度。当不同的编码长度之间的区分度越小,解码时将它们区分开的难度也越大。另外,如果不同的编码单位出现的概率不同,我们还可以使用霍夫曼编码(Huffman coding)的思想来进一步优化脉冲间隔编码的效率。比如说在一个待发送的文件中“0”的个数大于“1”的个数,使用较短的间隔代表“0”,长的间隔代表“1”,可以使总的发送时间更短。

OQPSK

观察QPSK的星座映射图,我们可以发现从00 到 11 和从10 到01之间的相位跳变都是\pi。这样导致调制出来的信号会有一个相位的突变,如下图中红圈部分所示:

图. QPSK调制中会出现相位翻转为pi的情况

​ 这些相位跳变在实际系统中是不希望出现的,通常系统处理相位的跳变的时候都会出现问题。例如当信号通过低通滤波器时,这种相位翻转会导致较大的幅值波动,进而影响解码的成功率。

​ 为了解决这一问题,我们可以使用偏移四相键控(Offset QPSK, OQPSK)。 OQPSK方法是基于QPSK的I/Q调制方式,基本跟QPSK是类似的。I路信号和QPSK相同,而Q路信号向后错位半个周期。这样一来I路和Q路信号翻转的位置相差半个周期,也就是说I路和Q路信号不会出现同时翻转,信号相位最大只能变化\frac{\pi}{2}

​ 下图分别展示了OQPSK的I、Q基带信号、分别调制了信息的两路信号以及叠加后的信号。

图. I/Q信号和调制后的OQPSK信号

QAM

​ 之前介绍的BPSK,QPSK和8PSK的星座图里点的数量依次增加,那是否还可以继续增加到16PSK呢?

​ 如果在单位圆上平均分配16个数据点,相邻两点之间的间距就会比8PSK更近,抗噪声的效果会进一步变差。我们重新审视一下星座图,如果把星座图的坐标系看作是极坐标系,则里面某个数据点的极角代表了信号相位,这个数据点距离原点的距离代表了信号幅度。为了让星座图上相邻的两个数据点距离稍远一些,我们不能把数据点限定在单位圆上。这样一来,我们需要**结合调幅和调相两种调制方式**,这种方式被称作正交相位调制(Quadrature Amplitude Modulation, QAM)。在前面的相位调制方法中,不管是BPSK,QPSK还是8PSK,信号的幅度始终是不变的。而在QAM调制中,信号的幅度可以同时变化。

​ 下图展示了16-QAM、32-QAM和64-QAM的星座图:

图. 16-QAM、32-QAM和64-QAM的星座图

​QAM调制方式进一步增加了每个数据点包含的信息量,提高了传输效率。

思考:基于前的BPSK,QPSK的代码,如何实现QAM的算法。

OFDM

正交频分多路复用(Orthogonal Frequency Division Multiplexing)是802.11协议中频繁出现的一项调制技术,802.11a,802.11g,802.11n,802.11ac等协议均使用OFDM作为调制方式,可以这么说,也正是由于OFDM的加入,使得WiFi的速率得到了很大的提高。因此OFDM是与每个人密切相关、无时无刻不在使用的一项技术。

​ 大家可能注意到了,不管是前面的BPSK,QPSK,8PSK还是QAM等,调制信号的时候使用的都是一个频率,即都使用的是f。那么如果要进一步提高数据发送的效率,很自然的一个想法是能不能使用多个频率,在每个频率上使用BPSK,QPSK,8PSK或者QAM来进行调制。如果在接收端我们又能将不同频率的数据分开,对每个频率单独解码的话,我们就显然能够达到更高的速率。这其实就是OFDM的基本思想,其中OFDM中OF就是指使用多个正交的频率,从而保证不同频率数据叠加到一起的时候不会互相干扰。

​ 为了说明OFDM的原理,我们需要首先介绍**多载波调制** (Multi-Carrier Modulation, MCM)技术。OFDM是MCM技术的一类。

​ 多载波调制将要传输数据分开调制到不同频率上,我们首先将要传输的数据分开对应到不同的传输频率,即串行比特流分成多个并行的子比特流。然后每一个子比特流调制到不同的子载波上进行传输,它和单载波调制原理的对比如下图:

图. 单载波和多载波调制原理对比

​ 可以看到,单载波调制只发送一路信号,而多载波调制可以发送多路叠加到一起的信号,这多路信号的每一路频率都不相同。 直观上看,最简单粗暴的方法是在接收端使用带通滤波器就可以分离出每一路信号,当然实际上我们不需要这样。使用带通滤波器的一个基本要求是:多载波调制的每一路信号之间干扰要尽可能的小,因此如何有效的选择这些载波的频率是多载波调制中的一个关键。

思考:应该如何选择多载波调制中每一个子载波的频率,才能满足这个要求呢?

​ 一个最直接简单的思路是让两个子载波频率差异尽量大,这样两个子载波之间的互相干扰就会比较小,但很显然这样编码的效率是比较低的。

​ OFDM提供了另外的一个思路,设第m路子载波的表达式为\phi_m(t)=e^{j2\pi f_m t},其中f_m为第m路子载波的频率。为了使任意两个不同的子载波之间干扰尽可能的小,我们希望这两个子载波之间体现出“正交性”,那么什么叫做两个频率之间的正交呢? 这个概念比较抽象,两个频率正交能够使得我们解码过程中两个频率对应的信号之间不互相干扰。这里,我们可以认为在一个码元长度T_c内二者相乘的积分为0,接下来我们解释为什么满足这样的性质能够保证两个正交频率信号叠加他们之间不互相干扰。令

\int_0^{T_c}e^{j2\pi f_i t}(e^{j2\pi f_j t})^*dt=\int_0^{T_c}e^{j2\pi (f_i-f_j) t}dt=\frac{sin(\pi \Delta f T_c)}{\pi \Delta f}e^{j\pi \Delta f T_c}=0

​ 其中\Delta f = f_i-f_j,从公式中可以看出,要满足正交性,需满足\Delta f = \frac{n}{T_c}n为正整数。即任意两个子载波的频率差是\frac{1}{T_c}的正整数倍,因此我们可以设计子载波的频率,使得相邻子载波的频率差为\frac{1}{T_c},这种设计就是OFDM中采用的子载波频率。如果将频率最小的子载波的频率设置为\frac{1}{T_c}的话,也就说所有子载波的频率都为\frac{1}{T_c}的整数倍。

​为了深入理解“正交性”的概念,可以参考下图:

图. OFDM中子载波的正交性

​ 各子载波上的码元长度都为T_c,因此它们的频谱在\frac{1}{T_c}处都为0。间隔为\frac{1}{T_c}的子载波叠加后,各子信道的频率样本间不存在相互干扰(例如子载波2和子载波3的频谱在\frac{1}{T_c}处的输出都为0)。

OFDM声波信号实现

图中展示了三个子载波的频谱,它们的中心频率分别为1/Tc,2/Tc,3/Tc。在每个子载波的中心频率处,其他所有子载波的强度均为0,因此,各子信道的频率样本间不存在相互干扰,容易分离每个子信道的信息。

所以OFDM可以如下来实现,使用多路正交的频率,每一路频率上使用之前我们说过的调制方式,多路信号叠加到一起。

这里我们以QPSK调制基带信号为基础,使用4路正交的子载波,即在每一路子载波上使用QPSK,最终实现一个简单的OFDM调制解调功能。为了简化代码,这里的调制部分省略了添加模拟信道噪声的步骤。

调制:

%% 生成信号
  function OFDMmodulator(codes, fileName)
  %输入参数:
  %codes: 待调制的数据,0/1数组
  %fileName:保存到本地的信号文件
  %调用样例:
  %OFDMmodulator([1,1,0,0,0,1,1,0], 'data')
  %调用结果:
  %同文件夹下生成一个‘data.wav’音频文件
  fs = 48000;
  T = 0.025; %周期为1/40s
  N = 4;    %采用4路子载波进行OFDM调制
  f = (1 : N)' / T; % 4路子载波的频率为40,80,120,160Hz 
  
  %将信号长度补齐到8的倍数(4路子载波,每个QPSK码元代表2bit)
  cLen = length(codes);
  L = 2 * N;
  add0 = mod(cLen, L);
  if add0 ~= 0
      codes = [codes, zeros(1, L - add0)];
      cLen = cLen + L - add0;
  end
  
  t = (0 : 1/fs : T - 1/fs);
  
  %生成I信号和Q信号
  sigCarriers = exp(1j*2*pi*f*t);
  
  %生成两路基带信号,并相加
  sigL = size(sigCarriers, 2); % 信号片段的长度
  sig = zeros(N, sigL * cLen / L);
  for i = 1 : cLen / L
    % QPSK 调制
      % 计算相位的I和Q值
      phaseI = (1 - 2 * codes(i * L - 7 : 2 : i * L))' * sqrt(2) / 2; 
      phaseQ = (1 - 2 * codes(i * L - 6 : 2 : i * L))' * sqrt(2) / 2;
      sig(:, (i - 1) * sigL + 1 : i * sigL) = (phaseI + 1j * phaseQ) .* sigCarriers;
  end
  
  sig = sum(sig, 1);
  sig = sig / max(abs(sig));
  % 取实部
  sig = real(sig);
  audiowrite([fileName, '.wav'], sig, fs);
  
  end

​ 发送端可以将这个调制好的声音播放出去,这在手机上就可以进行,然后接收端通过录音将声音接收下来,然后使用下面的算法进行解调,整个过程跟真实的无线数据收发一致。

​ 主要的解调代码如下:


  function codes = OFDMdemodulator(fileName)
%输入参数:
%fileName:调制数据得到的信号文件
%输出:
%codes: 解调结果,0/1数组
%调用样例:(同文件夹内需要有'data.wav'文件)
%OFDMdemodulator(‘data’)
%调用结果:
%输出[1,1,0,0,0,1,1,0]
[sig, fs] = audioread([fileName, '.wav']);
sig = sig';
T = 0.025;
N = 4;
f = (1 : N)' / T;
L = 2 * N;

sigL = fs*T;

cLen = L * length(sig) / sigL;
codes = zeros(1, cLen);

for i = 1 : cLen / L

    seg = sig((i - 1) * sigL + 1 : i * sigL)

    % 通过FFT求对应频率的频谱
    sigFFT = fft(seg);
    sigFFT = sigFFT(1+1:N+1);

    % 绘制星座图
    figure
    scatter(real(sigFFT),imag(sigFFT))
    
    % 通过星座图的实部/虚部符号解调信息
    I = (1 - sign(real(sigFFT)))/2;
    Q = (1 - sign(imag(sigFFT)))/2;

    codes(i * L - 7 : 2 : i * L) = I;
    codes(i * L - 6 : 2 : i * L) = Q;

end

end

与QPSK不同,我们利用FFT对信号的频谱进行分析。通过频谱分析的方式进行信号解调。大家也可以对调制过程中的每个子载波信号绘制频谱,验证OFDM的调制方式,加深对OFDM子载波正交性的理解。

​ 如果我们将上述的Matlab实现的调制和解调代码实现到手机上去的话,再结合手机的播放声音和录音的功能,就很容易实现一个基于声波的无线传输系统。大家可能会看到有很多关于声音的传输的前沿论文和软件,他们的基本实现都是以此为基础的,例如就有论文专门研究如何实现声波上的OFDM,我们再这里就跟大家直接进行展示。理解了这个,大家也可以动手去尝试一下。

​注意,我们这里给的OFDM的调制解调方式跟真实的会有一些差别,这里主要是方便为了大家理解。我们介绍的过程是产生不同频率的正交信号,然后每一路上调制叠加。

真实的调制解调过程并不需要产生不同频率的正交信号,而是通过傅里叶逆变换ifft,指定不同子载波频率后通过傅里叶逆变换生成要调制的数据。而在接收端通过傅里叶变化直接将各个子载波的信息解码出来。

具体傅里叶变换和傅里叶逆变换的方法可以参见傅里叶分析一章节。

  • 发送端:发送的数据为c_k,基于x[n] = \frac{1}{N}\sum_{k=0}^{N-1} c_k e^{j2\pi \frac{k}{N}n}.,我们可以生成要发送的信号x[n]。此时发送的信号有两个特点:
  • 有不同的正交频率组成,即e^{j2\pi \frac{k}{N}n}
  • 每一个正交频率对应的参数即为编码的信息。例如可以为c_k = I_k + Q_k*j
  • 接收端:收到数据后,对数据进行傅里叶分析,这样我们能够从接收到的数据里面计算出c_k,从而计算出I_kQ_k,从而解调数据。

基于这一主要思路,大家可以尝试一下OFDM的实现,并思考这样实现的好处是什么。

​ 当然完整的OFDM比这个更复杂,例如还会添加循环冗余的前缀等等,不过大家理解了OFDM的基本操作后,很多其他的技术部分也就比较好理解了,也能够从基本操作出发不断完善了。强烈建议大家都去相对完整地实现一次OFDM方法,一定会有很大的收获。基于现在的这些基础知识,请大家相信实现OFDM不会有你们想的那么复杂。

参考资料和文献

  1. 《信号与系统(第二版)》