Skip to content

Commit

Permalink
Merge pull request #269 from anarkiwi/consis
Browse files Browse the repository at this point in the history
Add sample clock consistency test.
  • Loading branch information
anarkiwi authored May 9, 2024
2 parents 0f80b0a + 5a2ad40 commit f749590
Show file tree
Hide file tree
Showing 19 changed files with 246 additions and 163 deletions.
13 changes: 11 additions & 2 deletions grc/iqtlabs_tuneable_test_source.block.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,28 @@ documentation: |-
complex samples proportional to frequency.
parameters:
freq: initial frequency.
freq_divisor: value to divide requested frequency by, to produce samples.
templates:
imports: from gnuradio import iqtlabs
make: iqtlabs.tuneable_test_source(${freq_divisor})
make: >
iqtlabs.tuneable_test_source(
${freq}, ${freq_divisor})
cpp_templates:
includes: ['#include <gnuradio/iqtlabs/tuneable_test_source.h>']
declarations: 'iqtlabs::tuneable_test_source::sptr ${id};'
make: 'this->${id} = iqtlabs::tuneable_test_source::make(${freq_divisor});'
make: >
this->${id} = iqtlabs::tuneable_test_source::make(
${freq}, ${freq_divisor});
link: ['libgnuradio-iqtlabs.so']

parameters:
- id: freq
label: freq_divisor
dtype: float
default: 1e9
- id: freq_divisor
label: freq_divisor
dtype: float
Expand Down
2 changes: 1 addition & 1 deletion include/gnuradio/iqtlabs/tuneable_test_source.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ class IQTLABS_API tuneable_test_source : virtual public gr::sync_block {
* class. iqtlabs::tuneable_test_source::make is the public interface for
* creating new instances.
*/
static sptr make(float divisor);
static sptr make(double freq, double divisor);
};

} // namespace iqtlabs
Expand Down
59 changes: 33 additions & 26 deletions lib/iq_inference_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,9 @@ iq_inference_impl::iq_inference_impl(
model_server_(model_server), confidence_(confidence),
n_inference_(n_inference), samp_rate_(samp_rate),
power_inference_(power_inference), background_(background),
inference_count_(0), running_(true), last_rx_freq_(0), last_rx_time_(0),
samples_since_tag_(0), sample_clock_(0), last_full_time_(0) {
inference_count_(n_inference), running_(true), last_rx_freq_(0),
last_rx_time_(0), samples_since_tag_(0), sample_clock_(0),
last_full_time_(0) {
batch_ = vlen_ * n_vlen_;
samples_lookback_.reset(new gr_complex[batch_ * sample_buffer]);
unsigned int alignment = volk_get_alignment();
Expand All @@ -267,7 +268,6 @@ iq_inference_impl::iq_inference_impl(
new std::thread(&iq_inference_impl::background_run_inference_, this));
}
torchserve_client_.reset(new torchserve_client(host_, port_));
set_output_multiple(n_vlen_);
message_port_register_out(INFERENCE_KEY);
}

Expand Down Expand Up @@ -409,9 +409,10 @@ void iq_inference_impl::process_items_(COUNT_T power_in_count,
if (*samples_total_ == 0) {
continue;
}
if (n_inference_ > 0 && ++inference_count_ % n_inference_) {
if (n_inference_ > 0 && --inference_count_) {
continue;
}
inference_count_ = n_inference_;
// TODO: we select one slice in time (samples and power),
// where at least one sample exceeded the minimum. We could
// potentially select more samples either side for example.
Expand Down Expand Up @@ -455,7 +456,7 @@ int iq_inference_impl::general_work(int noutput_items,
gr_vector_void_star &output_items) {
COUNT_T samples_in_count = ninput_items[0];
COUNT_T power_in_count = ninput_items[1];
COUNT_T in_first = nitems_read(1);
COUNT_T power_read_first = nitems_read(1);
const gr_complex *samples_in =
static_cast<const gr_complex *>(input_items[0]);
const float *power_in = static_cast<const float *>(input_items[1]);
Expand All @@ -469,21 +470,6 @@ int iq_inference_impl::general_work(int noutput_items,
int(std::min(samples_in_count, power_in_count) / n_vlen_) * n_vlen_;
power_in_count = samples_in_count;

while (!json_q_.empty()) {
std::string json;
json_q_.pop(json);
out_buf_.insert(out_buf_.end(), json.begin(), json.end());
}

if (!out_buf_.empty()) {
auto out = static_cast<char *>(output_items[0]);
leftover = std::min(out_buf_.size(), (COUNT_T)noutput_items);
auto from = out_buf_.begin();
auto to = from + leftover;
std::copy(from, to, out);
out_buf_.erase(from, to);
}

get_tags_in_window(all_tags, 1, 0, power_in_count);
get_tags(tag_, all_tags, rx_freq_tags, rx_times, power_in_count);

Expand All @@ -501,15 +487,15 @@ int iq_inference_impl::general_work(int noutput_items,
for (COUNT_T t = 0; t < rx_freq_tags.size(); ++t) {
const auto &tag = rx_freq_tags[t];
const TIME_T rx_time = rx_times[t];
const auto rel = tag.offset - in_first;
in_first += rel;
const auto rel = tag.offset - power_read;

// TODO: in theory we might have a vector with more than one frequency's
// samples, as the SDR probably isn't vector aligned. In practice this
// should not happen in the most common Ettus low power workaround state,
// because tags are delayed until after re-tuning has been verified.
if (rel > 0) {
process_items_(rel, power_read, power_in, consumed);
power_read += rel;
}

const FREQ_T rx_freq = GET_FREQ(tag);
Expand All @@ -518,13 +504,34 @@ int iq_inference_impl::general_work(int noutput_items,
last_rx_time_ = rx_time;
samples_since_tag_ = 0;
}
if (consumed < power_in_count) {
process_items_(power_in_count - consumed, power_read, power_in, consumed);
if (consumed < samples_in_count) {
process_items_(samples_in_count - consumed, power_read, power_in,
consumed);
}
}

consume(0, samples_in_count);
consume(1, consumed);
consume_each(consumed);

while (!json_q_.empty()) {
std::string json;
json_q_.pop(json);
out_buf_.insert(out_buf_.end(), json.begin(), json.end());
}

if (!out_buf_.empty()) {
auto out = static_cast<char *>(output_items[0]);
leftover = std::min(out_buf_.size(), (COUNT_T)noutput_items);
auto from = out_buf_.begin();
auto to = from + leftover;
std::copy(from, to, out);
out_buf_.erase(from, to);
}

if (consumed != samples_in_count) {
d_logger->error("mismatch consumed {} versus in count {}", consumed,
samples_in_count);
}

return leftover;
}

Expand Down
15 changes: 10 additions & 5 deletions lib/tuneable_test_source_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -209,17 +209,22 @@ namespace gr {
namespace iqtlabs {

using output_type = gr_complex;
tuneable_test_source::sptr tuneable_test_source::make(float freq_divisor) {
return gnuradio::make_block_sptr<tuneable_test_source_impl>(freq_divisor);
tuneable_test_source::sptr tuneable_test_source::make(double freq,
double freq_divisor) {
return gnuradio::make_block_sptr<tuneable_test_source_impl>(freq,
freq_divisor);
}

tuneable_test_source_impl::tuneable_test_source_impl(float freq_divisor)
tuneable_test_source_impl::tuneable_test_source_impl(double freq,
double freq_divisor)
: gr::sync_block("tuneable_test_source", gr::io_signature::make(0, 0, 0),
gr::io_signature::make(1 /* min outputs */,
1 /*max outputs */,
sizeof(output_type))),
d_freq_divisor(freq_divisor), last_freq(0), last_sample(gr_complex(0, 0)),
tag_now(false) {
d_freq_divisor(freq_divisor), last_freq(freq),
last_sample(gr_complex(0, 0)), tag_now(false) {
last_sample =
gr_complex(last_freq / d_freq_divisor, last_freq / d_freq_divisor);
message_port_register_in(CMD_KEY);
set_msg_handler(CMD_KEY, [this](const pmt::pmt_t &msg) { recv_cmd(msg); });
}
Expand Down
2 changes: 1 addition & 1 deletion lib/tuneable_test_source_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ class tuneable_test_source_impl : public tuneable_test_source, base_impl {
bool tag_now;

public:
tuneable_test_source_impl(float freq_divisor);
tuneable_test_source_impl(double freq, double freq_divisor);
~tuneable_test_source_impl();

int work(int noutput_items, gr_vector_const_void_star &input_items,
Expand Down
11 changes: 7 additions & 4 deletions python/iqtlabs/bindings/docstrings/retune_fft_pydoc_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,21 @@
*
*/
#include "pydoc_macros.h"
#define D(...) DOC(gr, iqtlabs, __VA_ARGS__)
#define D(...) DOC(gr,iqtlabs, __VA_ARGS__ )
/*
This file contains placeholders for docstrings for the Python bindings.
Do not edit! These were automatically extracted during the binding process
and will be overwritten during the build process
*/


static const char* __doc_gr_iqtlabs_retune_fft = R"doc()doc";

static const char *__doc_gr_iqtlabs_retune_fft = R"doc()doc";


static const char* __doc_gr_iqtlabs_retune_fft_retune_fft = R"doc()doc";
static const char *__doc_gr_iqtlabs_retune_fft_retune_fft = R"doc()doc";


static const char* __doc_gr_iqtlabs_retune_fft_make = R"doc()doc";
static const char *__doc_gr_iqtlabs_retune_fft_make = R"doc()doc";


Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,21 @@
*
*/
#include "pydoc_macros.h"
#define D(...) DOC(gr, iqtlabs, __VA_ARGS__)
#define D(...) DOC(gr,iqtlabs, __VA_ARGS__ )
/*
This file contains placeholders for docstrings for the Python bindings.
Do not edit! These were automatically extracted during the binding process
and will be overwritten during the build process
*/


static const char* __doc_gr_iqtlabs_retune_pre_fft = R"doc()doc";

static const char *__doc_gr_iqtlabs_retune_pre_fft = R"doc()doc";


static const char* __doc_gr_iqtlabs_retune_pre_fft_retune_pre_fft = R"doc()doc";
static const char *__doc_gr_iqtlabs_retune_pre_fft_retune_pre_fft = R"doc()doc";


static const char* __doc_gr_iqtlabs_retune_pre_fft_make = R"doc()doc";
static const char *__doc_gr_iqtlabs_retune_pre_fft_make = R"doc()doc";


Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,21 @@
*
*/
#include "pydoc_macros.h"
#define D(...) DOC(gr, iqtlabs, __VA_ARGS__)
#define D(...) DOC(gr,iqtlabs, __VA_ARGS__ )
/*
This file contains placeholders for docstrings for the Python bindings.
Do not edit! These were automatically extracted during the binding process
and will be overwritten during the build process
*/


static const char* __doc_gr_iqtlabs_tuneable_test_source = R"doc()doc";

static const char *__doc_gr_iqtlabs_tuneable_test_source = R"doc()doc";


static const char* __doc_gr_iqtlabs_tuneable_test_source_tuneable_test_source =
R"doc()doc";
static const char *__doc_gr_iqtlabs_tuneable_test_source_tuneable_test_source = R"doc()doc";


static const char* __doc_gr_iqtlabs_tuneable_test_source_make = R"doc()doc";
static const char *__doc_gr_iqtlabs_tuneable_test_source_make = R"doc()doc";


67 changes: 41 additions & 26 deletions python/iqtlabs/bindings/retune_fft_python.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,37 +30,52 @@ namespace py = pybind11;
void bind_retune_fft(py::module& m)
{

using retune_fft = ::gr::iqtlabs::retune_fft;
using retune_fft = ::gr::iqtlabs::retune_fft;


py::class_<retune_fft, gr::block, gr::basic_block, std::shared_ptr<retune_fft>>(
m, "retune_fft", D(retune_fft))
py::class_<retune_fft, gr::block, gr::basic_block,
std::shared_ptr<retune_fft>>(m, "retune_fft", D(retune_fft))

.def(py::init(&retune_fft::make),
py::arg("tag"),
py::arg("nfft"),
py::arg("samp_rate"),
py::arg("tune_jitter_hz"),
py::arg("freq_start"),
py::arg("freq_end"),
py::arg("tune_step_hz"),
py::arg("tune_step_fft"),
py::arg("skip_tune_step_fft"),
py::arg("fft_min"),
py::arg("fft_max"),
py::arg("sdir"),
py::arg("write_step_fft"),
py::arg("bucket_range"),
py::arg("tuning_ranges"),
py::arg("description"),
py::arg("rotate_secs"),
py::arg("pre_fft"),
py::arg("tag_now"),
py::arg("low_power_hold_down"),
py::arg("slew_rx_time"),
py::arg("peak_fft_range"),
D(retune_fft, make))
py::arg("tag"),
py::arg("nfft"),
py::arg("samp_rate"),
py::arg("tune_jitter_hz"),
py::arg("freq_start"),
py::arg("freq_end"),
py::arg("tune_step_hz"),
py::arg("tune_step_fft"),
py::arg("skip_tune_step_fft"),
py::arg("fft_min"),
py::arg("fft_max"),
py::arg("sdir"),
py::arg("write_step_fft"),
py::arg("bucket_range"),
py::arg("tuning_ranges"),
py::arg("description"),
py::arg("rotate_secs"),
py::arg("pre_fft"),
py::arg("tag_now"),
py::arg("low_power_hold_down"),
py::arg("slew_rx_time"),
py::arg("peak_fft_range"),
D(retune_fft,make)
)




;




}








Loading

0 comments on commit f749590

Please sign in to comment.