自动信道检测算法

时间:2017-03-26 19:38:45

标签: algorithm detection channel spectrum software-defined-radio

我目前正致力于利用SDR对无线电信号(更确切地说,我对L波段卫星信道感兴趣)执行自动调制分类(AMC)的业余时间项目。我希望它能够发现功率谱中的信道及其频率和带宽,因此我可以将AMC的应用指向此步骤的输出。

我的第一个(天真)方法相当简单:在每N个样本(比如1024)应用窗口函数后,对最后一个N执行FFT,计算功率谱的估计并应用一些指数平滑以减少噪声。然后,在平滑的功率谱中,找到最大和最小信号电平,基于两个电平的加权平均值计算一些阈值,并使用该阈值来确定哪个频率区域属于信道。

这在我的单元测试中很有效(一个QPSK通道+高斯噪声)。然而,在现实生活中,我要么得到一些渠道,要么有很多误报。当然,我可以通过在阈值计算中微调权重来解决这个问题,但是它不再是自动的。

我一直在对Google进行一些研究,但也许我没有使用正确的搜索关键字,或者对此主题没有真正的兴趣(这很奇怪,因为频率扫描仪必须以某种方式执行此任务)。 / p>

我怎样才能找到平均重量的合适值?也许比计算整个光谱的阈值有更好的方法?

2 个答案:

答案 0 :(得分:0)

你的平滑方法似乎有点适得其反:为什么足够长的DFT中的噪声形成类似“尖锐”的形状?你最有可能以这种方式抑制窄带载波。

然后:真的有很多信号检测器,很多只​​是基于光谱中的能量检测(就像你的方法一样)。

然而,估算器必须越好,您需要的信号就越多。您是在寻找20 kHz宽的窄带信道,还是数十兆赫的高速QPSK卫星下行信道?你对通道/脉冲形状有什么了解吗?自相关γ

这是一个广泛的领域,所以我建议你看看已经有效的东西:

SebastianMüller的gr-inspector是经过验证且非常棒的自动通道检测器,对于某些类型的传输,它还可以推断出调制参数。

查看demo video(dubstep警告!);你似乎在草绘的内容看起来像这样:

gr-inspector energy detection

但是:这只是它可以做的事情之一。

更重要的是:基于DFT的能带检测实际上只是您可以检测信号的众多事情之一。例如,它不会检测扩频传输,例如GPS。为此,您需要了解扩散技术或至少需要一个基于自相关的大型探测器。

答案 1 :(得分:0)

在考虑了MarcusMüller的建议之后,我开发了一种算法,该算法仍然依赖于全局能量阈值,但也依赖于噪声基底的估计。它可以通过多种方式进行改进,但由于其最简单的实现已经提供了可接受的实际捕获结果(同样,L波段捕获速度为250 ksps),我相信它可能是其他人开始的良好基础。

该算法的核心思想是基于噪声功率的连续估计来计算能量阈值,并在每次更新频谱图时对其进行更新。该估计跟踪在所有FFT运行期间每个FFT仓获得的最大和最小水平,使用它们来估计该仓中的PSD并丢弃异常值(即,信道,杂散......)。该算法将在每个固定数量的样本中执行。更正式地说:

算法参数:

int N        /* spectrogram length (FFT bins) */
complex x[N] /* last N samples */
float alpha  /* spectrogram smoothing factor between 0 (infinite smoothing,
                spectrogram will never be updated) and 1 (no smoothing at all) */
float beta   /* level decay factor between 0 (levels will never decay) and 1
                (levels will be equal to the spectrogram). */
float gamma  /* smooth factor applied to updates of the current noise estimation
                between 0 (no updates allowed) and 1 /* no smoothing */
float SNR    /* detection threshold above noise, in dB */

alphabetagamma的推荐值分别为1e-21e-3.5

<强>变量:

complex dft[N]  /* Fourier transform of the last N samples */
float spect[N]  /* smoothed spectrogram */
float spmin[N]  /* lower levels for spectrogram bins */
float spmax[N]  /* upper levels for spectrogram bins */
int runs        /* FFT run counter (initially zero) */
float N0        /* Current noise level estimation */
float new_N0    /* New noise level estimation */
float min_pwr   /* Minimum power density found */
int min_pwr_bin /* FFT bin where min_pwr is */
int valid       /* Number of valid bins for noise estimation */
int min_runs    /* Minimum number of runs required to detect channels */

<强>算法:

min_runs = max(2. / alpha, 1. / beta)
dft = FFT(x);
++runs;
if (runs == 1) then /* First FFT run */
    spect = dft * conj(dft) /* |FFT(x)|^2 */
    spmin = spect /* Copy spect to spmin */
    spmax = spect /* Copy spect to spmax */
    N0    = min(spect); /* First noise estimation */
else
    /* Smooth spectrogram w.r.t the previous run */
    spect += alpha * (dft * conj(dft) - spect)

    /* Update levels. This has to be performed element-wise  */
    new_N0 = 0
    valid = 0
    min_pwr = INFINITY
    min_pwr_bin = -1
    for (int i = 0; i < N; ++i)
        /* Update current lower levels or raise them */
        if (spect[i] < spmin[i]) then
            spmin[i] = spect[i]
        else
            spmin[i] += beta * (spect[i] - spmin[i]);
        end

        /* Update current upper levels or decrease them */
        if (spect[i] > spmax[i]) then
            spmax[i] = spect[i]
        else
            spmax[i] += beta * (spect[i] - spmax[i]);
        end

        if (runs > min_runs) then
            /* Use previous N0 estimation to detect outliers */
            if (spmin[i] < N0 or N0 < spmax[i]) then
                new_N0 += spect[i]
                ++valid
            end

            /* Update current minimum power */
            if (spect[i] < min_pwr) then
                min_pwr = spect[i]
                min_pwr_bin = i
            end
        end
    end

    /*
     * Check whether levels have stabilized and update noise
     * estimation accordingly
     */
    if (runs > min_runs) then
        /*
         * This is a key step: if the number of valid bins is
         * 0 this means that our previous estimation was
         * absolutely wrong. We reset it with a cruder estimation
         * based on where the minimum value of the current
         * spectrogram was found
         */

        if (valid == 0) then
            N0 = .5 * (spmin[min_pwr_bin] + spmax[min_pwr_bin])
        else
            N0 += gamma * (new_N0 / valid - N0)
        end

        /*
         * Detect channels based on this threshold (trivial,
         * not detailed)
         */

        detect_channels(spect, 10^(SNR / 10) * N0)
    end
end

即使这个算法强烈假设噪声基底是平坦的(在大多数情况下,如在现实世界的无线电中那样是假的,调谐器输出通过一个响应不平坦的低通滤波器),它甚至可以工作如果这种情况不成立。这些是针对不同alpha值N = 4096SNR = 3 dB的算法结果。噪声估计标记为黄色,通道阈值为绿色,上层为红色,频谱图为白色,下层为青色。我还提供了每次FFT运行后N0估计的演变:

alpha = 1e-1的结果: Results for alpha = 1e-1

alpha = 1e-2的结果。请注意当谱图变得更清晰时,有效箱的数量是如何减少的: Results for alpha = 1e-2

alpha = 1e-3的结果。在这种情况下,电平非常紧,噪声基底显然不平坦,从一个FFT运行到另一个FFT运行无效。在这种情况下,我们回到寻找具有最低功率密度的箱的粗略估计:

Results for alpha = 1e-3 min_runs计算至关重要。为了防止噪声水平升级(这是跟随信道而不是噪声基底),我们必须至少等待2. / alpha FFT运行才能信任信号电平。这个值是通过实验发现的:在我之前的实现中,我直观地使用了1. / alphaalpha = 1e-3惨遭失败:

Updrift

我还没有在其他场景(如突发传输)上测试过这种情况,由于最小/最大电平的持续性,此算法可能无法像连续通道一样执行,并且可能无法将突发传输检测为异常值。但是,鉴于我正在使用的渠道类型,现在不是优先考虑的事项。