Я хотел бы кодировать мой собственный блок приемника с 1 входным портом и 0 выходными портами для GNU Radio в C ++. Я прочитал и выполнил шаги, описанные здесь:
я использую
Используя gr_modtool, я создал новый модуль «jammertrap». Внутри я создал блок «Bandpower». Это создало среди других трех файлов
bandpower.h:
#ifndef INCLUDED_JAMMERTRAP_BANDPOWER_H
#define INCLUDED_JAMMERTRAP_BANDPOWER_H
#include <jammertrap/api.h>
#include <gnuradio/block.h>
namespace gr
{
namespace jammertrap
{
class JAMMERTRAP_API bandpower : virtual public gr::block
{
public:
typedef boost::shared_ptr<bandpower> sptr;
// Return a shared_ptr to a new instance of jammertrap::bandpower.
// To avoid accidental use of raw pointers, jammertrap::bandpower's constructor is in a private implementation class.
// jammertrap::bandpower::make is the public interface for creating new instances.
static sptr make();
};
} // namespace jammertrap
} // namespace gr
#endif /* INCLUDED_JAMMERTRAP_BANDPOWER_H */
bandpower_impl.h:
#ifndef INCLUDED_JAMMERTRAP_BANDPOWER_IMPL_H
#define INCLUDED_JAMMERTRAP_BANDPOWER_IMPL_H
#include <jammertrap/bandpower.h>
namespace gr
{
namespace jammertrap
{
class bandpower_impl : public bandpower
{
private:
double d_bandpower_;
public:
bandpower_impl();
~bandpower_impl();
void forecast (int noutput_items, gr_vector_int &ninput_items_required);
// Where all the action really happens
int general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items);
// Returns the calculated RMS Bandpower
double get_bandpower();
};
} // namespace jammertrap
} // namespace gr
#endif /* INCLUDED_JAMMERTRAP_BANDPOWER_IMPL_H */
bandpower_impl.cc:
#ifdef HAVE_CONFIG_H
#include "config.h"#endif
#include <gnuradio/io_signature.h>
#include "bandpower_impl.h"
namespace gr
{
namespace jammertrap
{
bandpower::sptr
bandpower::make()
{
return gnuradio::get_initial_sptr (new bandpower_impl());
}
// The private constructor
bandpower_impl::bandpower_impl() : gr::block("bandpower", gr::io_signature::make(1, 1, sizeof(gr_complex)), gr::io_signature::make(0, 0, 0))
{
d_bandpower_ = 0;
}
// Our virtual destructor
bandpower_impl::~bandpower_impl()
{}
void bandpower_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required)
{
// ninput_items_required[0] = noutput_items;
}
int bandpower_impl::general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items)
{
const gr_complex *in = (const gr_complex *) input_items[0];
d_bandpower_ = 0;
for(int i = 0; i < noutput_items; i++)
{
d_bandpower_ += (in[i].real() * in[i].real()) + (in[i].imag() * in[i].imag());
}
d_bandpower_ = sqrt(d_bandpower_ / noutput_items);
// Tell runtime system how many input items we consumed on each input stream.
consume_each (noutput_items);
// Tell runtime system how many output items we produced
return noutput_items;
}
double bandpower_impl::get_bandpower()
{
return d_bandpower_;
}
} /* namespace jammertrap */
} /* namespace gr */
Чтобы создать и установить этот новый блок, я ввел следующие команды в / home / sdr / gnuradio / gr-jammertrap / build:
Этот блок приемника «bandpower» должен принимать элементы типа gr_complex, вычислять среднюю принятую мощность и сохранять это значение в закрытом элементе «d_bandpower_».
Дополнительно я определил метод «get_bandpower ()», чтобы получить сохраненное значение.
Внутри другой программы я создал класс потокового графа с двумя блоками
osmosdr::source:sptr osmosdr_source_;
gr::jammertrap::bandpower::sptr bandpower_measurement_;
и создал их с
osmosdr_source_ = osmosdr::source::make(std::string());
bandpower_measurement_ = gr::jammertrap::bandpower::make();
После запуска потокового графика я хочу прочитать рассчитанную пропускную способность, вызвав get_bandpower (), но Eclipse не показывает метод «bandpower_measurement _-> get_bandpower ()»
Что я забыл написать в bandpower.h, bandpower_impl.h или bandpower_impl.cc?
Публичный API нормального макета OOT находится в bandpower.h
так что вы должны добавить
virtual double get_bandpower() = 0;
в этом файле.
Затем вы перегружаете / внедряете это, как и вы, в _impl.cc
/_impl.h
,
Кстати, я немного возражаю против математики, стоящей за вашей реализацией: как noutput_items
т.е. количество доступных входных элементов, изменяется в зависимости от заполнения буфера / времени выполнения, ваша «длина усреднения» не постоянна, что означает, что если ваш потоковый график работает быстро, ваши буферы будут обычно заполнены, а длина усреднения будет высокой, в «струйка», длина будет намного меньше (до noutput_items==1
в крайнем случае). Следовательно, дисперсия вашей оценки мощности будет зависеть от вычислительных аспектов.
Это не очень хорошая вещь. Лучше работать с постоянным количеством предметов, которые вы усредняете. В вашем случае вы можете использовать set_output_multiple
(поскольку приемник также является блоком синхронизации, это также влияет на входные кратные значения), чтобы гарантировать, что вы всегда получите кратное фиксированного числа.
Кроме этого, уже есть блоки, которые могут делать то, что вы хотите:
level()
который делает так же, как ваш get_bandpower
(кроме √ (.))signal()
метод, который делает то, что ваш get_bandpower
делает. Загрузка ЦП относительно невелика — на самом деле это просто определение величины для каждой выборки, а затем 123 реальных умножения + 123 реальных сложения на 123 выборки, в фильтре все SIMD увеличились, поэтому в основном менее 1 FMAC на выборку.Других решений пока нет …