1. CSI相位信息

  测量到的第i个子载波上的CSI相位信息 θ ~ i \tilde{\theta}_{i} θ~i
θ ~ i = θ i + 2 π K i Δ t N + β + Z f \tilde{\theta}_{i}=\theta_{i}+\frac{2 \pi K_{i} \Delta t}{N}+\beta+Z_{f} θ~i=θi+N2πKiΔt+β+Zf其中 θ i \theta_{i} θi为真实相位, Δ t \Delta t Δt为定时误差偏移(或者说时延), β \beta β是设备引起的随机相位偏移, Z f Z_{f} Zf是测量过程中的随机噪声。 K i K_{i} Ki是子载波索引(在IEEE 802.11n中范围是[-28,28]),N为FFT点数,N = 64.
在这里插入图片描述

2. 线性相位去噪(两步:解卷绕+线性变换)

目的:去除上式中中间两项。
  对于接收器,等式中间两项噪声在传输期间保持不变,线性相位去噪引入仅与真实相位相关,并对于每个子载波传输期间一致的变量值:
a = θ ~ n − θ ~ 1 K n − K 1 b = 1 n ∑ i = 1 n θ ~ i \begin{aligned} a &=\frac{\tilde{\theta}_{n}-\tilde{\theta}_{1}}{K_{n}-K_{1}} \\ b &=\frac{1}{n} \sum_{i=1}^{n} \tilde{\theta}_{i} \end{aligned} ab=KnK1θ~nθ~1=n1i=1nθ~i其中 θ ~ \tilde{\theta} θ~是原始相位,n一般为30,去噪后的相位为:
θ ^ i = θ ~ i − a k i − b = θ i − θ n − θ 1 K n − K 1 K i − ∑ i = 1 n θ i n \hat{\theta}_{i}=\tilde{\theta}_{i}-a k_{i}-b=\theta_{i}-\frac{\theta_{n}-\theta_{1}}{K_{n}-K_{1}} K i-\frac{\sum_{i=1}^{n} \theta_{i}}{n} θ^i=θ~iakib=θiKnK1θnθ1Kini=1nθi
由于采集的CSI信号周期范围为 [ − π , π ] [-\pi, \pi] [π,π],临界点π和π处会发生反相。为获得对应的30个子载波的均匀分布,在线性变换之前首先得unwrap30个子载波的相位
在这里插入图片描述
(a)原始相位→(b)接卷绕相位→(c)线性去噪后的估计相位

3. 相位校准效果

参考论文《PhaseFi: Phase Fingerprinting for Indoor Localization with a Deep Learning Approach》
在这里插入图片描述

4. CSI线性相位去噪的python实现

实验用的一发三收HT20,代码针对一发三收的数据流,是以前参照widar2.0相位去噪思路写的,感觉效果差不多

import numpy as np

pi = np.pi

# 注意,ant_csi的维度为1*F*T
def CSI_sanitization(one_csi, two_csi, three_csi):
    M = 3  # 天线数量3
    N = 30  # 子载波数目30
    T = one_csi.shape[1]  # 总包数
    fi = 312.5 * 2  # 子载波间隔312.5 * 2
    csi_phase = np.zeros((M, N, T))
    for t in range(T):  # 遍历时间戳上的CSI包,每根天线上都有30个子载波
        csi_phase[0, :, t] = np.unwrap(np.angle(one_csi[:, t]))
        csi_phase[1, :, t] = np.unwrap(csi_phase[0, :, t] + np.angle(two_csi[:, t] * np.conj(one_csi[:, t])))
        csi_phase[2, :, t] = np.unwrap(csi_phase[1, :, t] + np.angle(three_csi[:, t] * np.conj(two_csi[:, t])))
        ai = np.tile(2 * pi * fi * np.array(range(N)), M)
        bi = np.ones(M * N)
        ci = np.concatenate((csi_phase[0, :, t], csi_phase[1, :, t], csi_phase[2, :, t]))
        A = np.dot(ai, ai)
        B = np.dot(ai, bi)
        C = np.dot(bi, bi)
        D = np.dot(ai, ci)
        E = np.dot(bi, ci)
        rho_opt = (B * E - C * D) / (A * C - B ** 2)
        beta_opt = (B * D - A * E) / (A * C - B ** 2)
        temp = np.tile(np.array(range(N)), M).reshape(M, N)
        csi_phase[:, :, t] = csi_phase[:, :, t] + 2 * pi * fi * temp * rho_opt + beta_opt
    antennaPair_One = abs(one_csi) * np.exp(1j * csi_phase[0, :, :])
    antennaPair_Two = abs(two_csi) * np.exp(1j * csi_phase[1, :, :])
    antennaPair_Three = abs(three_csi) * np.exp(1j * csi_phase[2, :, :])
    return antennaPair_One, antennaPair_Two, antennaPair_Three

用采集的数据验证效果:
在这里插入图片描述
线性去噪后每条子载波上能比较真实得反映出真实相位的变化情况。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐