Saturday, December 19, 2020

Re: Block with overlapping window - consume_each() in regard to set_history()

The issue turned out to be caused by unequal sample rates at the input of the autocorrelate block.
To properly calculate autocorrelation it needs time aligned samples. Due to some asymmetrical signal processing paths in flowgraph,
there was a small variable difference that irregularly messed up the results. This can be fixed by placing throttle blocks before autocorrelate with
arbitrary set sample rate - according to source.

Is there any more neat way of providing coherent sample rate between inputs of the block or sample synchronization?

Flowchart png:
Kind regards,
Marcin Wachowiak




On Fri, 18 Dec 2020 at 19:34, Marcin Wachowiak <marcin.r.wachowiak@gmail.com> wrote:
Hello,
I am having a hard time trying to correct a block that calculates autocorrelation with overlapping.
Having read about set_history(), consume_each()  behaviour of the block does not match my size calculations.
  • Should consume_each include the N-samples that are stored in history or not? (I guess history samples indices are calculated based on what is provided in consume_each())
The code of the block is as follows:
...
//setting parameters in constructor:
d_nonoverlap_size = d_snapshot_size-d_overlap_size;
set_history(d_overlap_size+1);

//determine input/output buffer sizes relationship (in connected blocks)
set_relative_rate(1.0/d_nonoverlap_size);
...

Then there is forecast:
...
// Setup input output relationship
for (int i=0; i<ninput_items_required.size(); i++)
ninput_items_required[i] = d_nonoverlap_size*noutput_items;
...

And general work:
int
autocorrelate_impl::general_work (int output_matrices,
gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
// Cast pointer
gr_complex *out = (gr_complex *) output_items[0];

// Create each output matrix
for (int i=0; i<output_matrices; i++)
{
// Form input matrix
for(int k=0; k<d_num_inputs; k++)
{
memcpy((void*)d_input_matrix.col(k).data(),
((gr_complex*)input_items[k]+i*d_nonoverlap_size),
sizeof(gr_complex)*d_snapshot_size);
}
// Make output pointer into matrix pointer
Eigen::Map<Eigen::MatrixXcf> out_matrix(out+d_num_inputs*d_num_inputs*i,d_num_inputs,d_num_inputs);

// Do autocorrelation

out_matrix = (1.0/d_snapshot_size)*d_input_matrix.transpose()*d_input_matrix.conjugate();
if (d_avg_method == 1)
out_matrix = 0.5*out_matrix+(0.5/d_snapshot_size)*d_J*out_matrix.conjugate()*d_J;
}

// Tell runtime system how many input items we consumed on
// each input stream.
consume_each (d_nonoverlap_size*output_matrices+d_overlap_size);

// Tell runtime system how many output items we produced.
return (output_matrices);
}

When the block is simulated in comparison to no (0) overlap it returns strange values probably due to sizing issues, some historical samples distort the result.


Whole code and more complex test case(music_algo_simulation_2rx_with_noise.grc) is available here: https://github.com/MarcinWachowiak/GNU-Radio-USRP-Beamforming
Please advise.
Kind regards,
Marcin Wachowiak

No comments:

Post a Comment