我目前正在实施符号时间恢复功能块。我们的想法是能够选择不同的TED(加德纳,过零,早晚,最大似然等)。在诸如M& M恢复的块中,循环的增益参数被明确表示(gain_omega和gain_mu),这可能难以正确。然而,contro_loop类更方便(循环特性可由"循环带宽"和"阻尼因子"(zeta)指定)。所以我的第一次测试开始于使用控制回路重新实现MM时钟恢复。该块的工作功能如下所示(评论为我的)
clock_recovery_mm_ff_impl::general_work(int noutput_items,
gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
const float *in = (const float *)input_items[0];
float *out = (float *)output_items[0];
int ii = 0; // input index
int oo = 0; // output index
int ni = ninput_items[0] - d_interp->ntaps(); // don't use more input than this
float mm_val;
while(oo < noutput_items && ii < ni ) {
// produce output sample
out[oo] = d_interp->interpolate(&in[ii], d_mu); //Interpolation
mm_val = slice(d_last_sample) * out[oo] - slice(out[oo]) * d_last_sample; // Error calculation
d_last_sample = out[oo];
//Loop filtering
d_omega = d_omega + d_gain_omega * mm_val; //Frequency
d_omega = d_omega_mid + gr::branchless_clip(d_omega-d_omega_mid, d_omega_lim); //Bound the frequency
d_mu = d_mu + d_omega + d_gain_mu * mm_val; //Phase
ii += (int)floor(d_mu); // Basepoint index
d_mu = d_mu - floor(d_mu); // Fractional interval
oo++;
}
consume_each(ii);
return oo;
}
这是我的代码。首先,控制循环初始化构造函数
loop(new gr::blocks::control_loop(0.02,(1 + d_omega_relative_limit)*omega,
(1 - d_omega_relative_limit)*omega))
首先,我想消除一些关于符号定时恢复的pll(上面的control_loop)的疑虑,特别是相位和频率范围(反过来用于包装)。从Costas循环中进行类比:载波相位被包裹在-2pi和+ 2pi之间,频率偏移被跟踪在-1和+1之间。了解原因非常简单。不幸的是,我无法理解符号恢复中的相位和频率跟踪。从m&amp; m块,在(1 + omega_relative_limit)和(1-omega_relative_limit)* omega之间跟踪频率,其中omega仅是每个符号的样本数。阶段在0和欧米茄之间被跟踪。我不明白为什么会这样,以及m&amp; m块为什么不包装它。这里的任何想法将不胜感激。 这是我的工作职能
debug_time_recovery_pam_test_1_impl::general_work (int noutput_items,
gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
// Tell runtime system how many output items we produced.
const float *in = (const float *)input_items[0];
float *out = (float *)output_items[0];
int ii = 0; // input index
int oo = 0; // output index
int ni = ninput_items[0] - d_interp->ntaps(); // don't use more input than this
float mm_val;
while(oo < noutput_items && ii < ni ) {
// produce output sample
out[oo] = d_interp->interpolate(&in[ii], d_mu);
//Calculating error
mm_val = slice(d_last_sample) * out[oo] - slice(out[oo]) * d_last_sample;
d_last_sample = out[oo];
//Loop filtering
loop->advance_loop(mm_val); // Filter the error
loop->frequency_limit(); //Stop frequency from wandering too far
//Loop phase and frequency
d_omega = loop->get_frequency();
d_mu = loop->get_phase();
//d_omega = d_omega + d_gain_omega * mm_val;
//d_omega = d_omega_mid + gr::branchless_clip(d_omega-d_omega_mid, d_omega_lim);
//d_mu = d_mu + d_omega + d_gain_mu * mm_val;
ii += (int)floor(d_mu); // Basepoint index
d_mu = d_mu - floor(d_mu);//Fractional interval
oo++;
}
consume_each(ii);
return oo;
}
我曾尝试在GFSK解调器中使用该块,但我收到了此错误
python: /build/gnuradio-bJXzXK/gnuradio-3.7.9.1/gnuradio-runtime/include/gnuradio/buffer.h:177: unsigned int gr::buffer::index_add(unsigned int, unsigned int): Assertion `s < d_bufsize' failed.
关于此错误的第一次谷歌搜索表明我以某种方式&#34;滥用&#34;调度程序,因为此错误位于API之下。我认为我从控制循环中计算d_omega和d_mu有点天真但不幸的是我不知道其他任何方式。另一种选择是使用模1计数器(递增或递减)但我想先探索这个选项。