Reputation: 91
I'm doing my first steps in gnuradio-companion and want to code my own out-of-three blocks in c++ for signal processing. I worked through the gnuradio tutorial and have some knowledge of c++ but I'm not an expert.
Sytem setup: Ubuntu 18.04.2 LTS GNU Radio-Companion 3.7.13.4
I want to use the grc-block "Random Source" to generate bytes and pass them to an interpolator out-of-three block that will create a pulse position symbol.
The "Random Source" block is configured as followed: Min: 0 Max: 4 (which is 2^M = count of pulse positions in a ppm symbol) Num Samples: 16 or 32 Repeat: Yes
My out-of-three block is an interpolation block in c++ and has one input and one output. The interpolation value in the constructor is 6000 which mean the relation ship for input:output is 1:6000. A function get the input in[0] as parameter and generate a vector of type gr_complex with the pulse at the position of the value of in[0] which can be [0, 1, 2, 3]. The vector with the ppm symbol will be returned to the work()-function.
Observed problems: First problem: if the "Random Source" generate a byte with the value 0x00 and I use std::cout to print the value of in[0] the following error is displayed in the terminal window that is running gnuradio-companion:
/home/xyz/software/gnuradio/lib/python2.7/dist-packages/gnuradio/grc/gui/Dialogs.py:65: GtkWarning: gtk_text_buffer_emit_insert: assertion 'g_utf8_validate (text, len, NULL)' failed self.get_buffer().insert(self.get_buffer().get_end_iter(), line)
Solution: my solution is to copy the value of in[0] into an integer variable. The std::cout print the value as expected.
Second problem: If I set Num Samples of "Random Source" from 16 to 32 or higher and look watch the values of in[0] (that are copied into a int variable) in the terminal with std::cout the values are not matching the values that are generated by "Random Source" and displayed in a "QT GUI Time Sink". I really don't know what is causing the problem.
Solution: no solution so far...
This is the code of my out-of-three block
namespace gr {
namespace newmodulator {
pre_mod_v2::sptr
pre_mod_v2::make(int M, float duty_cycle, int samples_per_symbol)
{
return gnuradio::get_initial_sptr
(new pre_mod_v2_impl(M, duty_cycle, samples_per_symbol));
}
/*
* The private constructor
*/
pre_mod_v2_impl::pre_mod_v2_impl(int M, float duty_cycle, int samples_per_symbol)
: gr::sync_interpolator("pre_mod_v2",
gr::io_signature::make(1, 1, sizeof(char)),
gr::io_signature::make(1, 1, sizeof(gr_complex)), samples_per_symbol + 94) /*, d_M(M), d_duty_cycle(duty_cycle), d_samples_per_symbol(samples_per_symbol)*/
{
d_M = M;
d_duty_cycle = duty_cycle;
d_samples_per_symbol = samples_per_symbol;
//Variablen die in der Funktion set_vppm_symbol benötigt werden.
count_slots_per_symbol = 0;
vppm_slots = pow(2, M);
samples_per_slot = samples_per_symbol / vppm_slots;
pulse_length = (samples_per_symbol / 100 * duty_cycle);
symbol_value = 0;
//preamble = {{0, 5}, {0, 0}, {0, 0}, {0, 0}, {0, 5}};
preamble = {{0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 1}, {0, 0}, {0, 0},
{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
{0, 0}, {0, 0}, {0, 0}, {0, 1}};
}
/*
* Our virtual destructor.
*/
pre_mod_v2_impl::~pre_mod_v2_impl()
{
}
/* noutput_items = zahl (interpolation factor)
*/
int
pre_mod_v2_impl::work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
/* es werden Zeiger deklariert, die auf die Startadresse von input_items und output_items zeigen.
* Die Größe eines Zeigers wird durch typ* festgelegt
* ninput_items hat nur ein Element,
* während output_items so viele Elemente hat, wie oben durch den Interpolation-Faktor samples_per_symbol angegeben ist */
const unsigned char *in = (const unsigned char *) input_items[0];
gr_complex *out = (gr_complex *) output_items[0];
//std::cout << "symbol_value: " << in[0] << std::endl;
std::vector<gr_complex> vppm_symbols(d_samples_per_symbol + 94);
vppm_symbols = set_vppm_symbol(in, d_M, d_duty_cycle, d_samples_per_symbol);
//std::cout << "noutput_items: " << noutput_items << std::endl;
for (int i = 0; i < noutput_items; i++)
{
out[i] = vppm_symbols[i];
}
// es werden insgesamt noutput_items verarbeitet
consume_each(noutput_items);
// Tell runtime system how many output items we produced.
return noutput_items;
}
std::vector<gr_complex> pre_mod_v2_impl::set_vppm_symbol(const unsigned char* in, int &M, float &duty_cycle, int &samples_per_symbol)
{
symbol_value = in[0];
// if (!symbol_value){
// symbol_value = 0;
// }
std::cout << "symbol_value: " << static_cast<int>(in[0]) << std::endl;
std::vector<gr_complex> vppm_symbol(samples_per_symbol);
for (int i = (symbol_value * samples_per_slot); i < (symbol_value * samples_per_slot + pulse_length); i++)
{
vppm_symbol[i] = {static_cast<float>(1.0), 0};
}
vppm_symbol.insert(vppm_symbol.begin(), preamble.begin(), preamble.end());
return vppm_symbol;
}
} /* namespace newmodulator */
} /* namespace gr */
Upvotes: 1
Views: 1319
Reputation: 91
OK I solved my problem. I just add the code of my function set_vppm_symbol into my work function and deleted the line "consume_each(noutput_items)" although in the manual it is described to use the function what's irritating me. Now I'm getting the expected output.
Upvotes: 0