我看到的 Mueller 和 Muller 时钟恢复的实施为星座符号上的误差矢量幅度 (EVM) 添加了大量“噪声”或退化。这是在 GNU Radio 和 Python 中的手动脚本中独立完成的 - 给出了类似的结果。这是正常的吗?
我知道我需要调整此算法中的参数,但我无法接近足够的优化,它太嘈杂了。
在 GNU radio 和 python 两种实现中,对原始数据信号的唯一损害是 RRC 脉冲整形滤波器的性能。您可以看到这是一个几乎完美的接收星座,EVM < -60 dB,使用 300 的滤波器抽头和 0.35 的滚降因子。见下图。
然而,一旦我添加了 M&M 算法,我就没有运气接近这个,它会产生很多噪音。见下图。
这有点难以评估我以后可能会在模型中添加的损伤的真实程度,比如 AWGN。因为如果我在其中添加 AWGN,那么当使用 M&M 时,EVM 或 SNR 会变得更糟。
这是 GNU 无线电流程。
编辑请注意,在我的 python 代码中,Rx RRC 过滤器是在 M&M 之前执行的,但在 GNU 收音机中,我在 RRC 之前执行它,因为在 MM 块之前有一个 RRC 不起作用会在下面的流程中产生任何结果。
下面是 M&M python 算法,它来自 pySDR.com
samples = input_signal
interp = 16
samples_interpolated = signal.resample_poly(samples,interp,1)
mu = 2 #2 # initial estimate of phase of sample
out = np.zeros(len(samples) + 10, dtype=np.complex)
out_rail = np.zeros(len(samples) + 10, dtype=np.complex) # stores values, each iteration we need the previous 2 values plus current value
i_in = 0 # input samples index
i_out = 2 # output index (let first two outputs be 0)
while i_out < len(samples) and i_in < len(samples):
out[i_out] = samples_interpolated[i_in*interp + int(mu*interp)] # grab what we think is the "best" sample
out_rail[i_out] = int(np.real(out[i_out]) > 0) + 1j*int(np.imag(out[i_out]) > 0)
z = (out_rail[i_out] - out_rail[i_out-2]) * np.conj(out[i_out-1])
zz = (out[i_out] - out[i_out-2]) * np.conj(out_rail[i_out-1])
mm_val = np.real(zz - z)
mu += sps + 0.3*mm_val
i_in += int(np.floor(mu)) # round down to nearest int since we are using it as an index
mu = mu - np.floor(mu) # remove the integer part of mu
i_out += 1 # increment output index
out = out[2:i_out-1] # remove the first two, and anything after i_out (that was never filled out)