Using gr::fec::code::cc_encoder class in a hierarc

2019-06-02 12:43发布

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.

2条回答
聊天终结者
2楼-- · 2019-06-02 13:29

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.

查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-06-02 13:33

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);
}
查看更多
登录 后发表回答