我已经完成了GNU Radio中CCSDS(7,1 / 2)Viterbi解码器的仿真。解码器是默认GNU Radio“扩展的FEC解码器” python块(显示为
in stackoverflow)的C ++实现。代码如下所示。在不同的量化级别(1、3和无穷大量化)下,BPSK的BER曲线表明该块按预期工作。
目前,我正在用实际的硬件(商业单元)测试接收器。出乎意料的是,解码器的工作就像依赖于某些未知的初始条件一样,即有时它起作用而有时不起作用。人们必须重新启动流程图,并希望获得正确的神秘初始条件(与在不考虑相位模糊性的情况下使用BPSK / QPSK时的情况类似)。流程图使用NRZ-M,因此考虑了歧义分辨率。我在这里想念什么吗?
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gnuradio/io_signature.h>
#include "convDecoder_impl.h"
#include <gnuradio/fec/decoder.h>
#include <gnuradio/blocks/multiply_const_ff.h>
#include <gnuradio/blocks/add_const_ff.h>
#include <gnuradio/blocks/float_to_uchar.h>
#include <iostream>
namespace gr {
namespace ccsds {
convDecoder::sptr
convDecoder::make(int frame_size, std::vector<int> polys, int mode, int pad)
{
return gnuradio::get_initial_sptr
(new convDecoder_impl(frame_size, polys, mode, pad));
}
/*
* The private constructor
*/
convDecoder_impl::convDecoder_impl(int frame_size, std::vector<int> polys, int mode, int pad)
: gr::hier_block2("convDecoder",
gr::io_signature::make(1, 1, sizeof(float)),
gr::io_signature::make(1, 1, sizeof(unsigned char))),
tracking(0)
{
//Creating a decoder variable
int k = 7;
int rate = 2;
bool d_pad = (pad == 1) ? true : false;
cc_mode_t d_mode = get_mode(mode);
gr::fec::code::cc_decoder::sptr decoder_variable(gr::fec::code::cc_decoder::make(frame_size,k,rate,polys,0,-1,d_mode,d_pad));
/*if (tracking == 0){
std::cout << "input type : " << decoder_variable->get_input_conversion() << std::endl;
std::cout << "output type : " << decoder_variable->get_output_conversion() << std::endl;
std::cout << "input size : " << decoder_variable->get_input_item_size() << std::endl;
}
tracking +=1;*/
//Creating soft-decision converters
gr::blocks::multiply_const_ff::sptr multiplier(gr::blocks::multiply_const_ff::make(48.0));
gr::blocks::add_const_ff::sptr adder(gr::blocks::add_const_ff::make(128.0));
gr::blocks::float_to_uchar::sptr float_to_soft(gr::blocks::float_to_uchar::make());
//Creating a deployment variable
gr::fec::decoder::sptr decoder_deployment(gr::fec::decoder::make(decoder_variable,sizeof(unsigned char),sizeof(unsigned char)));
//Making connections
connect(self() , 0, multiplier , 0);
connect(multiplier, 0 , adder, 0);
connect(adder , 0, float_to_soft, 0);
connect(float_to_soft , 0 , decoder_deployment , 0);
connect(decoder_deployment , 0 , self() , 0);
}
cc_mode_t convDecoder_impl::get_mode(int mode)
{
switch(mode)
{
case 0:
return CC_STREAMING;
case 1:
return CC_TERMINATED;
case 2:
return CC_TRUNCATED;
case 3:
return CC_TAILBITING;
default:
return CC_STREAMING;
}
}
/*
* Our virtual destructor.
*/
convDecoder_impl::~convDecoder_impl()
{
}
} /* namespace ccsds */
} /* namespace gr */