我目前正致力于利用SDR对无线电信号(更确切地说,我对L波段卫星信道感兴趣)执行自动调制分类(AMC)的业余时间项目。我希望它能够发现功率谱中的信道及其频率和带宽,因此我可以将AMC的应用指向此步骤的输出。
我的第一个(天真)方法相当简单:在每N个样本(比如1024)应用窗口函数后,对最后一个N执行FFT,计算功率谱的估计并应用一些指数平滑以减少噪声。然后,在平滑的功率谱中,找到最大和最小信号电平,基于两个电平的加权平均值计算一些阈值,并使用该阈值来确定哪个频率区域属于信道。
这在我的单元测试中很有效(一个QPSK通道+高斯噪声)。然而,在现实生活中,我要么得到一些渠道,要么有很多误报。当然,我可以通过在阈值计算中微调权重来解决这个问题,但是它不再是自动的。
我一直在对Google进行一些研究,但也许我没有使用正确的搜索关键字,或者对此主题没有真正的兴趣(这很奇怪,因为频率扫描仪必须以某种方式执行此任务)。 / p>
我怎样才能找到平均重量的合适值?也许比计算整个光谱的阈值有更好的方法?
答案 0 :(得分:0)
你的平滑方法似乎有点适得其反:为什么足够长的DFT中的噪声形成类似“尖锐”的形状?你最有可能以这种方式抑制窄带载波。
然后:真的有很多信号检测器,很多只是基于光谱中的能量检测(就像你的方法一样)。
然而,估算器必须越好,您需要的信号就越多。您是在寻找20 kHz宽的窄带信道,还是数十兆赫的高速QPSK卫星下行信道?你对通道/脉冲形状有什么了解吗?自相关γ
这是一个广泛的领域,所以我建议你看看已经有效的东西:
SebastianMüller的gr-inspector
是经过验证且非常棒的自动通道检测器,对于某些类型的传输,它还可以推断出调制参数。
查看demo video(dubstep警告!);你似乎在草绘的内容看起来像这样:
但是:这只是它可以做的事情之一。
更重要的是:基于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 */
alpha
,beta
和gamma
的推荐值分别为1e-2
,1e-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 = 4096
和SNR = 3 dB
的算法结果。噪声估计标记为黄色,通道阈值为绿色,上层为红色,频谱图为白色,下层为青色。我还提供了每次FFT运行后N0
估计的演变:
alpha = 1e-2
的结果。请注意当谱图变得更清晰时,有效箱的数量是如何减少的:
alpha = 1e-3
的结果。在这种情况下,电平非常紧,噪声基底显然不平坦,从一个FFT运行到另一个FFT运行无效。在这种情况下,我们回到寻找具有最低功率密度的箱的粗略估计:
min_runs
计算至关重要。为了防止噪声水平升级(这是跟随信道而不是噪声基底),我们必须至少等待2. / alpha
FFT运行才能信任信号电平。这个值是通过实验发现的:在我之前的实现中,我直观地使用了1. / alpha
,alpha = 1e-3
惨遭失败:
我还没有在其他场景(如突发传输)上测试过这种情况,由于最小/最大电平的持续性,此算法可能无法像连续通道一样执行,并且可能无法将突发传输检测为异常值。但是,鉴于我正在使用的渠道类型,现在不是优先考虑的事项。