Сверточное декодирование в GNU Radio: неопределенность Витерби - PullRequest
0 голосов
/ 11 октября 2018

Я завершил моделирование декодера Витерби CCSDS (7,1 / 2) в GNU Radio.Декодер является реализацией C ++ стандартного блока Python GNU Radio «Extended FEC Decoder» (представлен в stackoverflow ).Код показан ниже.Кривая BER для BPSK при разных уровнях квантования (1, 3 и бесконечное квантование) показывает, что блок работает должным образом.BER В данный момент я тестирую приемник с реальным оборудованием (коммерческое устройство).Удивительно, но декодер работает так, как будто он зависит от некоторых неизвестных начальных условий, то есть иногда он работает, а иногда нет.Нужно перезапустить потоковую диаграмму и надеяться сделать загадочные начальные условия правильными [такой же опыт, как при работе с BPSK / QPSK без учета фазовой неоднозначности].Блок-схема использует NRZ-M, поэтому учитывается разрешение неоднозначности.Есть что-то, что я здесь скучаю?flowgaph

    #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 */
...