Я завершил моделирование декодера Витерби CCSDS (7,1 / 2) в GNU Radio.Декодер является реализацией C ++ стандартного блока Python GNU Radio «Extended FEC Decoder» (представлен в stackoverflow ).Код показан ниже.Кривая BER для BPSK при разных уровнях квантования (1, 3 и бесконечное квантование) показывает, что блок работает должным образом. В данный момент я тестирую приемник с реальным оборудованием (коммерческое устройство).Удивительно, но декодер работает так, как будто он зависит от некоторых неизвестных начальных условий, то есть иногда он работает, а иногда нет.Нужно перезапустить потоковую диаграмму и надеяться сделать загадочные начальные условия правильными [такой же опыт, как при работе с 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 */