Using gr::fec::code::cc_encoder class in a hierarchical block

删除回忆录丶 提交于 2020-01-14 04:52:41

问题


I have implemented a very basic C++ CCSDS convolutional encoder (k=7,r=1/2) and it works fine. However, it is very basic and it lacks options such as operational mode (CC_STREAMING, CC_TERMINATED, CC_TAILBITING, CC_TRUNCATED) etc ..etc. Therefore, I have decided to use the default gnuradio gr::fec::code::cc_encoder class. My coding superclass will include puncturing and other blocks and therefore everything will be in a hierarchical block. So far I'm putting the blocks one by one in the hierarchical block starting with gr::fec::code::cc_encoder. Below is my .cc implementation file.

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gnuradio/io_signature.h>
#include "debug_conv_encoder_impl.h"

namespace gr {
    namespace baseband {

debug_conv_encoder::sptr
debug_conv_encoder::make(int frame_size, std::vector<int> polys, int mode, int pad)
{
  return gnuradio::get_initial_sptr
    (new debug_conv_encoder_impl(frame_size, polys, mode, pad));
}

/*
 * The private constructor
 */
debug_conv_encoder_impl::debug_conv_encoder_impl(int frame_size, std::vector<int> polys, int mode, int pad)
  : gr::hier_block2("debug_conv_encoder",
          gr::io_signature::make(1, 1, sizeof(unsigned char)),
          gr::io_signature::make(1, 1, sizeof(unsigned char)))
{
  //Creating convolutional encoder
  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_encoder::sptr encoder(gr::fec::code::cc_encoder::make(frame_size,k,rate,polys,0,d_mode,d_pad));
  //connect(self(),0,self(),0); -- Works fine
  connect(self() , 0 , encoder , 0); // --gives an error
  connect(encoder , 0 , self() , 0); // --gives an error
  //connect(encoder);
}
cc_mode_t debug_conv_encoder_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.
 */
debug_conv_encoder_impl::~debug_conv_encoder_impl()
{
}


   } /* namespace baseband */
} /* namespace gr */

And here is the header file

#ifndef INCLUDED_BASEBAND_DEBUG_CONV_ENCODER_IMPL_H
#define INCLUDED_BASEBAND_DEBUG_CONV_ENCODER_IMPL_H

#include <baseband/debug_conv_encoder.h>
#include <gnuradio/fec/cc_encoder.h>
namespace gr {
  namespace baseband {

class debug_conv_encoder_impl : public debug_conv_encoder
{
 private:
    cc_mode_t get_mode(int mode);

 public:
  debug_conv_encoder_impl(int frame_size, std::vector<int> polys, int mode, int pad);
  ~debug_conv_encoder_impl();

   // Where all the action really happens
  };

    } // namespace baseband
 } // namespace gr

 #endif /* INCLUDED_BASEBAND_DEBUG_CONV_ENCODER_IMPL_H */

Unfortunately, compiling and linking the file (cmake .. && make) give this error:

xxx/GRC/baseband/gr-baseband/lib/debug_conv_encoder_impl.cc:53:39: error: no matching function for call to ‘gr::baseband::debug_conv_encoder_impl::connect(gr::hier_block2::opaque_self, int, gr::fec::generic_encoder::sptr&, int)’
   connect(self() , 0 , encoder , 0);
/usr/local/include/gnuradio/hier_block2.h:105:10: note:   no known conversion for argument 3 from ‘gr::fec::generic_encoder::sptr {aka boost::shared_ptr<gr::fec::generic_encoder>}’ to ‘gr::basic_block_sptr {aka boost::shared_ptr<gr::basic_block>}’

Basically, the line "gr::fec::generic_encoder::sptr {aka boost::shared_ptr}’ to ‘gr::basic_block_sptr {aka boost::shared_ptr}’" implies that the shared pointer gr::fec::generic_encoder can't be converted to gr::basic_block as required by hier_block2.connect (basic_block_sptr src, int src_port, basic_block_sptr dst, int dst_port).

I have created many hierarchical blocks this way but never encountered this error. I'm pretty sure there is something big I'm missing. Any help will be highly appreciated. And by the way, please let me know if more information is needed. Cheers.


回答1:


I was finally able to fix the issue. Turns out the Gnu radio FECAPI provides coder variables to define the FEC property (classes derived from the gr::fec::generic_encoder class eg. cc_encoder, ldpc_encoder etc) and deployment variables ( which interact with the scheduler and the coder variable in the GNU radio flowgraph. The deployment variable "gr::fec::encoder" can be used with a number of coder variables such as the cc_encoder or LDPC encoder. The work function now looks as shown below. The OOT now compiles and works as it should.

debug_conv_encoder_impl::debug_conv_encoder_impl(int frame_size, std::vector<int> polys, int mode, int pad)
  : gr::hier_block2("debug_conv_encoder",
          gr::io_signature::make(1, 1, sizeof(unsigned char)),
          gr::io_signature::make(1, 1, sizeof(unsigned char)))
{
  //Creating a coder 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_encoder::sptr coder_variable(gr::fec::code::cc_encoder::make(frame_size,k,rate,polys,0,d_mode,d_pad));

  //Creating a deployment variable
  gr::fec::encoder::sptr coder_deployment(gr::fec::encoder::make(coder_variable,sizeof(unsigned char),sizeof(unsigned char)));
  connect(self() , 0 , coder_deployment , 0);
  connect(coder_deployment , 0 , self() , 0);
  //connect(encoder);
}



回答2:


cc_encoder is not a block, hence you can't connect it in a flow graph like a block.

In fact, you shouldn't be able to instantiate it, even, as it's an abstract base class only:

https://gnuradio.org/doc/doxygen/classgr_1_1fec_1_1code_1_1cc__encoder.html

I'm not quite sure what an encoder you need, but in any case, this class isn't the way to go.



来源:https://stackoverflow.com/questions/49671107/using-grfeccodecc-encoder-class-in-a-hierarchical-block

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!