diff options
author | Josh Morman <mormjb@gmail.com> | 2020-04-23 10:59:04 -0400 |
---|---|---|
committer | Josh Morman <mormjb@gmail.com> | 2020-06-04 10:05:48 -0400 |
commit | 9f49495b36004af83372a31bb658f32fbb334599 (patch) | |
tree | 3dcfd9a4549af722f1de320c9f6758aa5679e278 | |
parent | 25d5e75363199413239e5c69dda2c41faca896ac (diff) |
uhd: add pybind11 bindings
-rw-r--r-- | gr-uhd/python/uhd/CMakeLists.txt | 2 | ||||
-rw-r--r-- | gr-uhd/python/uhd/__init__.py | 70 | ||||
-rw-r--r-- | gr-uhd/python/uhd/bindings/CMakeLists.txt | 19 | ||||
-rw-r--r-- | gr-uhd/python/uhd/bindings/amsg_source_python.cc | 43 | ||||
-rw-r--r-- | gr-uhd/python/uhd/bindings/docstrings/amsg_source_pydoc_template.h | 30 | ||||
-rw-r--r-- | gr-uhd/python/uhd/bindings/docstrings/usrp_block_pydoc_template.h | 234 | ||||
-rw-r--r-- | gr-uhd/python/uhd/bindings/docstrings/usrp_sink_pydoc_template.h | 66 | ||||
-rw-r--r-- | gr-uhd/python/uhd/bindings/docstrings/usrp_source_pydoc_template.h | 87 | ||||
-rw-r--r-- | gr-uhd/python/uhd/bindings/python_bindings.cc | 46 | ||||
-rw-r--r-- | gr-uhd/python/uhd/bindings/usrp_block_python.cc | 441 | ||||
-rw-r--r-- | gr-uhd/python/uhd/bindings/usrp_sink_python.cc | 129 | ||||
-rw-r--r-- | gr-uhd/python/uhd/bindings/usrp_source_python.cc | 175 | ||||
-rw-r--r-- | gr-uhd/python/uhd/qa_uhd.py | 2 |
13 files changed, 1317 insertions, 27 deletions
diff --git a/gr-uhd/python/uhd/CMakeLists.txt b/gr-uhd/python/uhd/CMakeLists.txt index f73dc68524..e6d34d8d6c 100644 --- a/gr-uhd/python/uhd/CMakeLists.txt +++ b/gr-uhd/python/uhd/CMakeLists.txt @@ -37,3 +37,5 @@ foreach(py_qa_test_file ${py_qa_test_files}) GR_ADD_TEST(${py_qa_test_name} ${QA_PYTHON_EXECUTABLE} -B ${py_qa_test_file}) endforeach(py_qa_test_file) endif(ENABLE_TESTING) + +add_subdirectory(bindings) diff --git a/gr-uhd/python/uhd/__init__.py b/gr-uhd/python/uhd/__init__.py index 0fa188ae23..3f24d98826 100644 --- a/gr-uhd/python/uhd/__init__.py +++ b/gr-uhd/python/uhd/__init__.py @@ -16,39 +16,43 @@ line. from __future__ import absolute_import from __future__ import unicode_literals +import uhd # TODO: verify uhd python is installed as a dependency for gr-uhd with python + ######################################################################## # Prepare uhd swig module to make it more pythonic ######################################################################## -def _prepare_uhd_swig(): +def _prepare_uhd_python(): try: - from . import uhd_swig + from . import uhd_python except ImportError: import os dirname, filename = os.path.split(os.path.abspath(__file__)) - __path__.append(os.path.join(dirname, "..", "..", "swig")) - from . import uhd_swig + __path__.append(os.path.join(dirname, "bindings")) + from . import uhd_python #some useful typedefs for the user - setattr(uhd_swig, 'freq_range_t', uhd_swig.meta_range_t) - setattr(uhd_swig, 'gain_range_t', uhd_swig.meta_range_t) + # setattr(uhd_python, 'freq_range_t', uhd_python.meta_range_t) + # setattr(uhd_python, 'gain_range_t', uhd_python.meta_range_t) + setattr(uhd_python, 'freq_range_t', uhd.types.MetaRange) + setattr(uhd_python, 'gain_range_t', uhd.types.MetaRange) #Make the python tune request object inherit from float #so that it can be passed in GRC as a frequency parameter. #The type checking in GRC will accept the tune request. #Also use kwargs to construct individual struct elements. - class tune_request_t(uhd_swig.tune_request_t, float): + class tune_request_t(uhd.types.TuneRequest): #, float): def __new__(self, *args, **kwargs): return float.__new__(self) def __float__(self): return self.target_freq def __init__(self, *args, **kwargs): super(tune_request_t, self).__init__(*args) for key, val in list(kwargs.items()): setattr(self, key, val) - setattr(uhd_swig, 'tune_request_t', tune_request_t) + setattr(uhd_python, 'tune_request_t', tune_request_t) #Make the python tune request object inherit from string #so that it can be passed in GRC as a string parameter. #The type checking in GRC will accept the device address. #Define the set/get item special methods for dict access. - class device_addr_t(uhd_swig.device_addr_t, str): + class device_addr_t(uhd.types.DeviceAddr): #, str): def __new__(self, *args): return str.__new__(self) def __getitem__(self, key): return self.get(key) def __setitem__(self, key, val): self.set(key, val) @@ -56,11 +60,15 @@ def _prepare_uhd_swig(): super(device_addr_t, self).__init__(*args) if args and isinstance(args[0], device_addr_t): for key in list(args[0].keys()): self[key] = args[0][key] - setattr(uhd_swig, 'device_addr_t', device_addr_t) + setattr(uhd_python, 'device_addr_t', device_addr_t) #make the streamer args take **kwargs on init - class stream_args_t(uhd_swig.stream_args_t): + class stream_args_t(uhd.usrp.StreamArgs): def __init__(self, *args, **kwargs): + # UHD Python API doesn't have default args for stream_args_t + # If empty args, then append empty str's + while len(args) < 2: + args += ("",) super(stream_args_t, self).__init__(*args) for key, val in list(kwargs.items()): #for some reason, I can't assign a list in the constructor @@ -70,28 +78,31 @@ def _prepare_uhd_swig(): elif key == 'args': self.args = device_addr_t(val) else: setattr(self, key, val) - setattr(uhd_swig, 'stream_args_t', stream_args_t) - #handle general things on all uhd_swig attributes + # FIXME: stream_args_t.channels.append does not work due to copy operation of STL vectors + setattr(uhd_python, 'stream_args_t', stream_args_t) + # setattr(uhd_python, 'stream_args_t', uhd.usrp.StreamArgs) + + #handle general things on all uhd_python attributes #Install the __str__ and __repr__ handlers if applicable #Create aliases for uhd swig attributes to avoid the "_t" - for attr in dir(uhd_swig): - myobj = getattr(uhd_swig, attr) + for attr in dir(uhd_python): + myobj = getattr(uhd_python, attr) if hasattr(myobj, 'to_string'): myobj.__repr__ = lambda o: o.to_string().strip() if hasattr(myobj, 'to_pp_string'): myobj.__str__ = lambda o: o.to_pp_string().strip() if hasattr(myobj, 'to_bool'): myobj.__nonzero__ = lambda o: o.to_bool() if hasattr(myobj, 'to_int'): myobj.__int__ = lambda o: o.to_int() if hasattr(myobj, 'to_real'): myobj.__float__ = lambda o: o.to_real() - if attr.endswith('_t'): setattr(uhd_swig, attr[:-2], myobj) + if attr.endswith('_t'): setattr(uhd_python, attr[:-2], myobj) #make a new find devices that casts everything with the pythonized device_addr_t which has __str__ def find_devices(*args, **kwargs): def to_pythonized_dev_addr(dev_addr): - new_dev_addr = uhd_swig.device_addr_t() + new_dev_addr = uhd_python.device_addr_t() for key in list(dev_addr.keys()): new_dev_addr[key] = dev_addr.get(key) return new_dev_addr - return __builtins__['map'](to_pythonized_dev_addr, uhd_swig.find_devices_raw(*args, **kwargs)) - setattr(uhd_swig, 'find_devices', find_devices) + return __builtins__['map'](to_pythonized_dev_addr, uhd_python.find_devices_raw(*args, **kwargs)) + setattr(uhd_python, 'find_devices', find_devices) #Cast constructor args (FIXME swig handle overloads?) for attr in ('usrp_source', 'usrp_sink', 'amsg_source'): @@ -112,16 +123,21 @@ def _prepare_uhd_swig(): if key in kwargs: args.append(kwargs[key]) return old_constructor(*args) return constructor_interceptor - setattr(uhd_swig, attr, constructor_factory(getattr(uhd_swig, attr))) + setattr(uhd_python, attr, constructor_factory(getattr(uhd_python, attr))) + + #FIXME: Aliases for UHD Python API - can this go away?? Do we need more?? + setattr(uhd_python, 'time_spec_t', uhd.types.TimeSpec) + #Aliases for deprecated constructors - setattr(uhd_swig, 'single_usrp_source', uhd_swig.usrp_source) - setattr(uhd_swig, 'single_usrp_sink', uhd_swig.usrp_sink) - setattr(uhd_swig, 'multi_usrp_source', uhd_swig.usrp_source) - setattr(uhd_swig, 'multi_usrp_sink', uhd_swig.usrp_sink) + #FIXME: Remove for 3.9?? + setattr(uhd_python, 'single_usrp_source', uhd_python.usrp_source) + setattr(uhd_python, 'single_usrp_sink', uhd_python.usrp_sink) + setattr(uhd_python, 'multi_usrp_source', uhd_python.usrp_source) + setattr(uhd_python, 'multi_usrp_sink', uhd_python.usrp_sink) ######################################################################## -# Initialize this module with the contents of uhd swig +# Initialize this module with the contents of uhd pybind ######################################################################## -_prepare_uhd_swig() -from .uhd_swig import * +_prepare_uhd_python() +from .uhd_python import * diff --git a/gr-uhd/python/uhd/bindings/CMakeLists.txt b/gr-uhd/python/uhd/bindings/CMakeLists.txt new file mode 100644 index 0000000000..880885462d --- /dev/null +++ b/gr-uhd/python/uhd/bindings/CMakeLists.txt @@ -0,0 +1,19 @@ +include(GrPybind) + +######################################################################## +# Python Bindings +######################################################################## + +list(APPEND uhd_python_files + amsg_source_python.cc + usrp_block_python.cc + usrp_sink_python.cc + usrp_source_python.cc + python_bindings.cc) + +GR_PYBIND_MAKE(uhd + ../../.. + gr::uhd + "${uhd_python_files}") + +install(TARGETS uhd_python DESTINATION ${GR_PYTHON_DIR}/gnuradio/uhd COMPONENT pythonapi) diff --git a/gr-uhd/python/uhd/bindings/amsg_source_python.cc b/gr-uhd/python/uhd/bindings/amsg_source_python.cc new file mode 100644 index 0000000000..2e3daacf2e --- /dev/null +++ b/gr-uhd/python/uhd/bindings/amsg_source_python.cc @@ -0,0 +1,43 @@ +/* + * Copyright 2020 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +/* This file is automatically generated using bindtool */ + +#include <pybind11/complex.h> +#include <pybind11/pybind11.h> +#include <pybind11/stl.h> + +namespace py = pybind11; + +#include <gnuradio/uhd/amsg_source.h> +// pydoc.h is automatically generated in the build directory +#include <amsg_source_pydoc.h> + +void bind_amsg_source(py::module& m) +{ + + using amsg_source = ::gr::uhd::amsg_source; + + + py::class_<amsg_source, std::shared_ptr<amsg_source>>( + m, "amsg_source", D(amsg_source)) + + .def(py::init(&amsg_source::make), + py::arg("device_addr"), + py::arg("msgq"), + D(amsg_source, make)) + + + .def_static("msg_to_async_metadata_t", + &amsg_source::msg_to_async_metadata_t, + py::arg("msg"), + D(amsg_source, msg_to_async_metadata_t)) + + ; +} diff --git a/gr-uhd/python/uhd/bindings/docstrings/amsg_source_pydoc_template.h b/gr-uhd/python/uhd/bindings/docstrings/amsg_source_pydoc_template.h new file mode 100644 index 0000000000..275c38042e --- /dev/null +++ b/gr-uhd/python/uhd/bindings/docstrings/amsg_source_pydoc_template.h @@ -0,0 +1,30 @@ +/* + * Copyright 2020 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#include "pydoc_macros.h" +#define D(...) DOC(gr, uhd, __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_uhd_amsg_source = R"doc()doc"; + + +static const char* __doc_gr_uhd_amsg_source_amsg_source_0 = R"doc()doc"; + + +static const char* __doc_gr_uhd_amsg_source_amsg_source_1 = R"doc()doc"; + + +static const char* __doc_gr_uhd_amsg_source_make = R"doc()doc"; + + +static const char* __doc_gr_uhd_amsg_source_msg_to_async_metadata_t = R"doc()doc"; diff --git a/gr-uhd/python/uhd/bindings/docstrings/usrp_block_pydoc_template.h b/gr-uhd/python/uhd/bindings/docstrings/usrp_block_pydoc_template.h new file mode 100644 index 0000000000..3ef0dd728b --- /dev/null +++ b/gr-uhd/python/uhd/bindings/docstrings/usrp_block_pydoc_template.h @@ -0,0 +1,234 @@ +/* + * Copyright 2020 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#include "pydoc_macros.h" +#define D(...) DOC(gr, uhd, __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_uhd_usrp_block = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_set_subdev_spec = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_subdev_spec = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_num_mboards = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_set_samp_rate = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_samp_rate = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_samp_rates = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_set_center_freq_0 = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_set_center_freq_1 = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_center_freq = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_freq_range = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_set_gain_0 = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_set_gain_1 = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_set_normalized_gain = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_gain_0 = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_gain_1 = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_normalized_gain = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_gain_names = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_gain_range_0 = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_gain_range_1 = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_set_antenna = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_antenna = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_antennas = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_set_bandwidth = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_bandwidth = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_bandwidth_range = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_sensor = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_sensor_names = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_dboard_sensor = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_dboard_sensor_names = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_mboard_sensor = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_mboard_sensor_names = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_time_source = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_time_sources = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_set_clock_source = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_clock_source = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_clock_sources = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_clock_rate = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_set_clock_rate = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_time_now = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_time_last_pps = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_set_time_now = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_set_time_next_pps = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_set_time_unknown_pps = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_set_command_time = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_clear_command_time = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_dboard_iface = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_device = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_set_user_register = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_set_time_source = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_set_stream_args = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_gpio_banks = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_set_gpio_attr = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_gpio_attr = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_filter_names = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_set_filter = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_block_get_filter = R"doc()doc"; + + +static const char* __doc_gr_uhd_cmd_chan_key = R"doc()doc"; + + +static const char* __doc_gr_uhd_cmd_gain_key = R"doc()doc"; + + +static const char* __doc_gr_uhd_cmd_freq_key = R"doc()doc"; + + +static const char* __doc_gr_uhd_cmd_lo_offset_key = R"doc()doc"; + + +static const char* __doc_gr_uhd_cmd_tune_key = R"doc()doc"; + + +static const char* __doc_gr_uhd_cmd_lo_freq_key = R"doc()doc"; + + +static const char* __doc_gr_uhd_cmd_dsp_freq_key = R"doc()doc"; + + +static const char* __doc_gr_uhd_cmd_rate_key = R"doc()doc"; + + +static const char* __doc_gr_uhd_cmd_bandwidth_key = R"doc()doc"; + + +static const char* __doc_gr_uhd_cmd_time_key = R"doc()doc"; + + +static const char* __doc_gr_uhd_cmd_mboard_key = R"doc()doc"; + + +static const char* __doc_gr_uhd_cmd_antenna_key = R"doc()doc"; + + +static const char* __doc_gr_uhd_cmd_direction_key = R"doc()doc"; + + +static const char* __doc_gr_uhd_cmd_tag_key = R"doc()doc"; + + +static const char* __doc_gr_uhd_ant_direction_rx = R"doc()doc"; + + +static const char* __doc_gr_uhd_ant_direction_tx = R"doc()doc"; diff --git a/gr-uhd/python/uhd/bindings/docstrings/usrp_sink_pydoc_template.h b/gr-uhd/python/uhd/bindings/docstrings/usrp_sink_pydoc_template.h new file mode 100644 index 0000000000..233a1f4c3c --- /dev/null +++ b/gr-uhd/python/uhd/bindings/docstrings/usrp_sink_pydoc_template.h @@ -0,0 +1,66 @@ +/* + * Copyright 2020 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#include "pydoc_macros.h" +#define D(...) DOC(gr, uhd, __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_uhd_usrp_sink = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_sink_usrp_sink_0 = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_sink_usrp_sink_1 = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_sink_make = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_sink_set_start_time = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_sink_get_usrp_info = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_sink_get_lo_names = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_sink_set_lo_source = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_sink_get_lo_source = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_sink_get_lo_sources = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_sink_set_lo_export_enabled = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_sink_get_lo_export_enabled = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_sink_set_lo_freq = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_sink_get_lo_freq = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_sink_get_lo_freq_range = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_sink_set_dc_offset = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_sink_set_iq_balance = R"doc()doc"; diff --git a/gr-uhd/python/uhd/bindings/docstrings/usrp_source_pydoc_template.h b/gr-uhd/python/uhd/bindings/docstrings/usrp_source_pydoc_template.h new file mode 100644 index 0000000000..f2d93f03a0 --- /dev/null +++ b/gr-uhd/python/uhd/bindings/docstrings/usrp_source_pydoc_template.h @@ -0,0 +1,87 @@ +/* + * Copyright 2020 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#include "pydoc_macros.h" +#define D(...) DOC(gr, uhd, __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_uhd_usrp_source = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_source_usrp_source_0 = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_source_usrp_source_1 = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_source_make = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_source_set_start_time = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_source_issue_stream_cmd = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_source_set_recv_timeout = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_source_get_usrp_info = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_source_get_lo_names = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_source_set_lo_source = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_source_get_lo_source = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_source_get_lo_sources = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_source_set_lo_export_enabled = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_source_get_lo_export_enabled = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_source_set_lo_freq = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_source_get_lo_freq = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_source_get_lo_freq_range = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_source_set_auto_dc_offset = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_source_set_dc_offset = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_source_set_auto_iq_balance = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_source_set_iq_balance = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_source_set_rx_agc = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_source_finite_acquisition = R"doc()doc"; + + +static const char* __doc_gr_uhd_usrp_source_finite_acquisition_v = R"doc()doc"; diff --git a/gr-uhd/python/uhd/bindings/python_bindings.cc b/gr-uhd/python/uhd/bindings/python_bindings.cc new file mode 100644 index 0000000000..eeb7c6e430 --- /dev/null +++ b/gr-uhd/python/uhd/bindings/python_bindings.cc @@ -0,0 +1,46 @@ + +/* + * Copyright 2020 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include <pybind11/pybind11.h> + +#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION +#include <numpy/arrayobject.h> + +namespace py = pybind11; + +void bind_amsg_source(py::module&); +void bind_usrp_block(py::module&); +void bind_usrp_sink(py::module&); +void bind_usrp_source(py::module&); + +// We need this hack because import_array() returns NULL +// for newer Python versions. +// This function is also necessary because it ensures access to the C API +// and removes a warning. +void* init_numpy() +{ + import_array(); + return NULL; +} + +PYBIND11_MODULE(uhd_python, m) +{ + // Initialize the numpy C API + // (otherwise we will see segmentation faults) + init_numpy(); + + // Allow access to base block methods + py::module::import("gnuradio.gr"); + + bind_amsg_source(m); + bind_usrp_block(m); + bind_usrp_sink(m); + bind_usrp_source(m); +} diff --git a/gr-uhd/python/uhd/bindings/usrp_block_python.cc b/gr-uhd/python/uhd/bindings/usrp_block_python.cc new file mode 100644 index 0000000000..7d25ce1a34 --- /dev/null +++ b/gr-uhd/python/uhd/bindings/usrp_block_python.cc @@ -0,0 +1,441 @@ +/* + * Copyright 2020 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +/* This file is automatically generated using bindtool */ + +#include <pybind11/complex.h> +#include <pybind11/pybind11.h> +#include <pybind11/stl.h> + +namespace py = pybind11; + +#include <gnuradio/uhd/usrp_block.h> +// pydoc.h is automatically generated in the build directory +#include <usrp_block_pydoc.h> + +void bind_usrp_block(py::module& m) +{ + + using usrp_block = ::gr::uhd::usrp_block; + + + py::class_<usrp_block, + gr::sync_block, + gr::block, + gr::basic_block, + std::shared_ptr<usrp_block>>(m, "usrp_block", D(usrp_block)) + + + .def("set_subdev_spec", + &usrp_block::set_subdev_spec, + py::arg("spec"), + py::arg("mboard") = 0, + D(usrp_block, set_subdev_spec)) + + + .def("get_subdev_spec", + &usrp_block::get_subdev_spec, + py::arg("mboard") = 0, + D(usrp_block, get_subdev_spec)) + + + .def("get_num_mboards", + &usrp_block::get_num_mboards, + D(usrp_block, get_num_mboards)) + + + .def("set_samp_rate", + &usrp_block::set_samp_rate, + py::arg("rate"), + D(usrp_block, set_samp_rate)) + + + .def("get_samp_rate", &usrp_block::get_samp_rate, D(usrp_block, get_samp_rate)) + + + .def("get_samp_rates", &usrp_block::get_samp_rates, D(usrp_block, get_samp_rates)) + + + .def("set_center_freq", + (uhd::tune_result_t(usrp_block::*)(uhd::tune_request_t const, size_t)) & + usrp_block::set_center_freq, + py::arg("tune_request"), + py::arg("chan") = 0, + D(usrp_block, set_center_freq, 0)) + + + .def("set_center_freq", + (uhd::tune_result_t(usrp_block::*)(double, size_t)) & + usrp_block::set_center_freq, + py::arg("freq"), + py::arg("chan") = 0, + D(usrp_block, set_center_freq, 1)) + + + .def("get_center_freq", + &usrp_block::get_center_freq, + py::arg("chan") = 0, + D(usrp_block, get_center_freq)) + + + .def("get_freq_range", + &usrp_block::get_freq_range, + py::arg("chan") = 0, + D(usrp_block, get_freq_range)) + + + .def("set_gain", + (void (usrp_block::*)(double, size_t)) & usrp_block::set_gain, + py::arg("gain"), + py::arg("chan") = 0, + D(usrp_block, set_gain, 0)) + + + .def("set_gain", + (void (usrp_block::*)(double, std::string const&, size_t)) & + usrp_block::set_gain, + py::arg("gain"), + py::arg("name"), + py::arg("chan") = 0, + D(usrp_block, set_gain, 1)) + + + .def("set_normalized_gain", + &usrp_block::set_normalized_gain, + py::arg("norm_gain"), + py::arg("chan") = 0, + D(usrp_block, set_normalized_gain)) + + + .def("get_gain", + (double (usrp_block::*)(size_t)) & usrp_block::get_gain, + py::arg("chan") = 0, + D(usrp_block, get_gain, 0)) + + + .def("get_gain", + (double (usrp_block::*)(std::string const&, size_t)) & usrp_block::get_gain, + py::arg("name"), + py::arg("chan") = 0, + D(usrp_block, get_gain, 1)) + + + .def("get_normalized_gain", + &usrp_block::get_normalized_gain, + py::arg("chan") = 0, + D(usrp_block, get_normalized_gain)) + + + .def("get_gain_names", + &usrp_block::get_gain_names, + py::arg("chan") = 0, + D(usrp_block, get_gain_names)) + + + .def("get_gain_range", + (uhd::gain_range_t(usrp_block::*)(size_t)) & usrp_block::get_gain_range, + py::arg("chan") = 0, + D(usrp_block, get_gain_range, 0)) + + + .def("get_gain_range", + (uhd::gain_range_t(usrp_block::*)(std::string const&, size_t)) & + usrp_block::get_gain_range, + py::arg("name"), + py::arg("chan") = 0, + D(usrp_block, get_gain_range, 1)) + + + .def("set_antenna", + &usrp_block::set_antenna, + py::arg("ant"), + py::arg("chan") = 0, + D(usrp_block, set_antenna)) + + + .def("get_antenna", + &usrp_block::get_antenna, + py::arg("chan") = 0, + D(usrp_block, get_antenna)) + + + .def("get_antennas", + &usrp_block::get_antennas, + py::arg("chan") = 0, + D(usrp_block, get_antennas)) + + + .def("set_bandwidth", + &usrp_block::set_bandwidth, + py::arg("bandwidth"), + py::arg("chan") = 0, + D(usrp_block, set_bandwidth)) + + + .def("get_bandwidth", + &usrp_block::get_bandwidth, + py::arg("chan") = 0, + D(usrp_block, get_bandwidth)) + + + .def("get_bandwidth_range", + &usrp_block::get_bandwidth_range, + py::arg("chan") = 0, + D(usrp_block, get_bandwidth_range)) + + + .def("get_sensor", + &usrp_block::get_sensor, + py::arg("name"), + py::arg("chan") = 0, + D(usrp_block, get_sensor)) + + + .def("get_sensor_names", + &usrp_block::get_sensor_names, + py::arg("chan") = 0, + D(usrp_block, get_sensor_names)) + + + .def("get_dboard_sensor", + &usrp_block::get_dboard_sensor, + py::arg("name"), + py::arg("chan") = 0, + D(usrp_block, get_dboard_sensor)) + + + .def("get_dboard_sensor_names", + &usrp_block::get_dboard_sensor_names, + py::arg("chan") = 0, + D(usrp_block, get_dboard_sensor_names)) + + + .def("get_mboard_sensor", + &usrp_block::get_mboard_sensor, + py::arg("name"), + py::arg("mboard") = 0, + D(usrp_block, get_mboard_sensor)) + + + .def("get_mboard_sensor_names", + &usrp_block::get_mboard_sensor_names, + py::arg("mboard") = 0, + D(usrp_block, get_mboard_sensor_names)) + + + .def("get_time_source", + &usrp_block::get_time_source, + py::arg("mboard"), + D(usrp_block, get_time_source)) + + + .def("get_time_sources", + &usrp_block::get_time_sources, + py::arg("mboard"), + D(usrp_block, get_time_sources)) + + + .def("set_clock_source", + &usrp_block::set_clock_source, + py::arg("source"), + py::arg("mboard") = 0, + D(usrp_block, set_clock_source)) + + + .def("get_clock_source", + &usrp_block::get_clock_source, + py::arg("mboard"), + D(usrp_block, get_clock_source)) + + + .def("get_clock_sources", + &usrp_block::get_clock_sources, + py::arg("mboard"), + D(usrp_block, get_clock_sources)) + + + .def("get_clock_rate", + &usrp_block::get_clock_rate, + py::arg("mboard") = 0, + D(usrp_block, get_clock_rate)) + + + .def("set_clock_rate", + &usrp_block::set_clock_rate, + py::arg("rate"), + py::arg("mboard") = 0, + D(usrp_block, set_clock_rate)) + + + .def("get_time_now", + &usrp_block::get_time_now, + py::arg("mboard") = 0, + D(usrp_block, get_time_now)) + + + .def("get_time_last_pps", + &usrp_block::get_time_last_pps, + py::arg("mboard") = 0, + D(usrp_block, get_time_last_pps)) + + + .def("set_time_now", + &usrp_block::set_time_now, + py::arg("time_spec"), + py::arg("mboard") = 0, + D(usrp_block, set_time_now)) + + + .def("set_time_next_pps", + &usrp_block::set_time_next_pps, + py::arg("time_spec"), + D(usrp_block, set_time_next_pps)) + + + .def("set_time_unknown_pps", + &usrp_block::set_time_unknown_pps, + py::arg("time_spec"), + D(usrp_block, set_time_unknown_pps)) + + + .def("set_command_time", + &usrp_block::set_command_time, + py::arg("time_spec"), + py::arg("mboard") = 0, + D(usrp_block, set_command_time)) + + + .def("clear_command_time", + &usrp_block::clear_command_time, + py::arg("mboard") = 0, + D(usrp_block, clear_command_time)) + + + .def("get_dboard_iface", + &usrp_block::get_dboard_iface, + py::arg("chan") = 0, + D(usrp_block, get_dboard_iface)) + + + .def("get_device", &usrp_block::get_device, D(usrp_block, get_device)) + + + .def("set_user_register", + &usrp_block::set_user_register, + py::arg("addr"), + py::arg("data"), + py::arg("mboard") = 0, + D(usrp_block, set_user_register)) + + + .def("set_time_source", + &usrp_block::set_time_source, + py::arg("source"), + py::arg("mboard") = 0, + D(usrp_block, set_time_source)) + + + .def("set_stream_args", + &usrp_block::set_stream_args, + py::arg("stream_args"), + D(usrp_block, set_stream_args)) + + + .def("get_gpio_banks", + &usrp_block::get_gpio_banks, + py::arg("mboard"), + D(usrp_block, get_gpio_banks)) + + + .def("set_gpio_attr", + &usrp_block::set_gpio_attr, + py::arg("bank"), + py::arg("attr"), + py::arg("value"), + py::arg("mask") = 4294967295U, + py::arg("mboard") = 0, + D(usrp_block, set_gpio_attr)) + + + .def("get_gpio_attr", + &usrp_block::get_gpio_attr, + py::arg("bank"), + py::arg("attr"), + py::arg("mboard") = 0, + D(usrp_block, get_gpio_attr)) + + + .def("get_filter_names", + &usrp_block::get_filter_names, + py::arg("search_mask") = "", + D(usrp_block, get_filter_names)) + + + .def("set_filter", + &usrp_block::set_filter, + py::arg("path"), + py::arg("filter"), + D(usrp_block, set_filter)) + + + .def("get_filter", + &usrp_block::get_filter, + py::arg("path"), + D(usrp_block, get_filter)) + + ; + + + m.def("cmd_chan_key", &::gr::uhd::cmd_chan_key, D(cmd_chan_key)); + + + m.def("cmd_gain_key", &::gr::uhd::cmd_gain_key, D(cmd_gain_key)); + + + m.def("cmd_freq_key", &::gr::uhd::cmd_freq_key, D(cmd_freq_key)); + + + m.def("cmd_lo_offset_key", &::gr::uhd::cmd_lo_offset_key, D(cmd_lo_offset_key)); + + + m.def("cmd_tune_key", &::gr::uhd::cmd_tune_key, D(cmd_tune_key)); + + + m.def("cmd_lo_freq_key", &::gr::uhd::cmd_lo_freq_key, D(cmd_lo_freq_key)); + + + m.def("cmd_dsp_freq_key", &::gr::uhd::cmd_dsp_freq_key, D(cmd_dsp_freq_key)); + + + m.def("cmd_rate_key", &::gr::uhd::cmd_rate_key, D(cmd_rate_key)); + + + m.def("cmd_bandwidth_key", &::gr::uhd::cmd_bandwidth_key, D(cmd_bandwidth_key)); + + + m.def("cmd_time_key", &::gr::uhd::cmd_time_key, D(cmd_time_key)); + + + m.def("cmd_mboard_key", &::gr::uhd::cmd_mboard_key, D(cmd_mboard_key)); + + + m.def("cmd_antenna_key", &::gr::uhd::cmd_antenna_key, D(cmd_antenna_key)); + + + m.def("cmd_direction_key", &::gr::uhd::cmd_direction_key, D(cmd_direction_key)); + + + m.def("cmd_tag_key", &::gr::uhd::cmd_tag_key, D(cmd_tag_key)); + + + m.def("ant_direction_rx", &::gr::uhd::ant_direction_rx, D(ant_direction_rx)); + + + m.def("ant_direction_tx", &::gr::uhd::ant_direction_tx, D(ant_direction_tx)); +} diff --git a/gr-uhd/python/uhd/bindings/usrp_sink_python.cc b/gr-uhd/python/uhd/bindings/usrp_sink_python.cc new file mode 100644 index 0000000000..bbc8ee0fe4 --- /dev/null +++ b/gr-uhd/python/uhd/bindings/usrp_sink_python.cc @@ -0,0 +1,129 @@ +/* + * Copyright 2020 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +/* This file is automatically generated using bindtool */ + +#include <pybind11/complex.h> +#include <pybind11/pybind11.h> +#include <pybind11/stl.h> + +namespace py = pybind11; + +#include <gnuradio/uhd/usrp_sink.h> +// pydoc.h is automatically generated in the build directory +#include <usrp_sink_pydoc.h> + +void bind_usrp_sink(py::module& m) +{ + + using usrp_sink = ::gr::uhd::usrp_sink; + + + py::class_<usrp_sink, gr::uhd::usrp_block, std::shared_ptr<usrp_sink>>( + m, "usrp_sink", D(usrp_sink)) + + .def(py::init(&usrp_sink::make), + py::arg("device_addr"), + py::arg("stream_args"), + py::arg("tsb_tag_name") = "", + D(usrp_sink, make)) + + + .def("set_start_time", + &usrp_sink::set_start_time, + py::arg("time"), + D(usrp_sink, set_start_time)) + + + .def("get_usrp_info", + &usrp_sink::get_usrp_info, + py::arg("chan") = 0, + D(usrp_sink, get_usrp_info)) + + + .def("get_lo_names", + &usrp_sink::get_lo_names, + py::arg("chan") = 0, + D(usrp_sink, get_lo_names)) + + + .def("set_lo_source", + &usrp_sink::set_lo_source, + py::arg("src"), + py::arg("name"), + py::arg("chan") = 0, + D(usrp_sink, set_lo_source)) + + + .def("get_lo_source", + &usrp_sink::get_lo_source, + py::arg("name"), + py::arg("chan") = 0, + D(usrp_sink, get_lo_source)) + + + .def("get_lo_sources", + &usrp_sink::get_lo_sources, + py::arg("name"), + py::arg("chan") = 0, + D(usrp_sink, get_lo_sources)) + + + .def("set_lo_export_enabled", + &usrp_sink::set_lo_export_enabled, + py::arg("enabled"), + py::arg("name"), + py::arg("chan") = 0, + D(usrp_sink, set_lo_export_enabled)) + + + .def("get_lo_export_enabled", + &usrp_sink::get_lo_export_enabled, + py::arg("name"), + py::arg("chan") = 0, + D(usrp_sink, get_lo_export_enabled)) + + + .def("set_lo_freq", + &usrp_sink::set_lo_freq, + py::arg("freq"), + py::arg("name"), + py::arg("chan") = 0, + D(usrp_sink, set_lo_freq)) + + + .def("get_lo_freq", + &usrp_sink::get_lo_freq, + py::arg("name"), + py::arg("chan") = 0, + D(usrp_sink, get_lo_freq)) + + + .def("get_lo_freq_range", + &usrp_sink::get_lo_freq_range, + py::arg("name"), + py::arg("chan") = 0, + D(usrp_sink, get_lo_freq_range)) + + + .def("set_dc_offset", + &usrp_sink::set_dc_offset, + py::arg("offset"), + py::arg("chan") = 0, + D(usrp_sink, set_dc_offset)) + + + .def("set_iq_balance", + &usrp_sink::set_iq_balance, + py::arg("correction"), + py::arg("chan") = 0, + D(usrp_sink, set_iq_balance)) + + ; +} diff --git a/gr-uhd/python/uhd/bindings/usrp_source_python.cc b/gr-uhd/python/uhd/bindings/usrp_source_python.cc new file mode 100644 index 0000000000..6834e23cd8 --- /dev/null +++ b/gr-uhd/python/uhd/bindings/usrp_source_python.cc @@ -0,0 +1,175 @@ +/* + * Copyright 2020 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +/* This file is automatically generated using bindtool */ + +#include <pybind11/complex.h> +#include <pybind11/pybind11.h> +#include <pybind11/stl.h> + +namespace py = pybind11; + +#include <gnuradio/uhd/usrp_source.h> +// pydoc.h is automatically generated in the build directory +#include <usrp_source_pydoc.h> + +void bind_usrp_source(py::module& m) +{ + + using usrp_source = ::gr::uhd::usrp_source; + + + py::class_<usrp_source, gr::uhd::usrp_block, std::shared_ptr<usrp_source>>( + m, "usrp_source", D(usrp_source)) + + .def(py::init(&usrp_source::make), + py::arg("device_addr"), + py::arg("stream_args"), + py::arg("issue_stream_cmd_on_start") = true, + D(usrp_source, make)) + + + .def("set_start_time", + &usrp_source::set_start_time, + py::arg("time"), + D(usrp_source, set_start_time)) + + + .def("issue_stream_cmd", + &usrp_source::issue_stream_cmd, + py::arg("cmd"), + D(usrp_source, issue_stream_cmd)) + + + .def("set_recv_timeout", + &usrp_source::set_recv_timeout, + py::arg("timeout"), + py::arg("one_packet") = true, + D(usrp_source, set_recv_timeout)) + + + .def("get_usrp_info", + &usrp_source::get_usrp_info, + py::arg("chan") = 0, + D(usrp_source, get_usrp_info)) + + + .def("get_lo_names", + &usrp_source::get_lo_names, + py::arg("chan") = 0, + D(usrp_source, get_lo_names)) + + + .def("set_lo_source", + &usrp_source::set_lo_source, + py::arg("src"), + py::arg("name"), + py::arg("chan") = 0, + D(usrp_source, set_lo_source)) + + + .def("get_lo_source", + &usrp_source::get_lo_source, + py::arg("name"), + py::arg("chan") = 0, + D(usrp_source, get_lo_source)) + + + .def("get_lo_sources", + &usrp_source::get_lo_sources, + py::arg("name"), + py::arg("chan") = 0, + D(usrp_source, get_lo_sources)) + + + .def("set_lo_export_enabled", + &usrp_source::set_lo_export_enabled, + py::arg("enabled"), + py::arg("name"), + py::arg("chan") = 0, + D(usrp_source, set_lo_export_enabled)) + + + .def("get_lo_export_enabled", + &usrp_source::get_lo_export_enabled, + py::arg("name"), + py::arg("chan") = 0, + D(usrp_source, get_lo_export_enabled)) + + + .def("set_lo_freq", + &usrp_source::set_lo_freq, + py::arg("freq"), + py::arg("name"), + py::arg("chan") = 0, + D(usrp_source, set_lo_freq)) + + + .def("get_lo_freq", + &usrp_source::get_lo_freq, + py::arg("name"), + py::arg("chan") = 0, + D(usrp_source, get_lo_freq)) + + + .def("get_lo_freq_range", + &usrp_source::get_lo_freq_range, + py::arg("name"), + py::arg("chan") = 0, + D(usrp_source, get_lo_freq_range)) + + + .def("set_auto_dc_offset", + &usrp_source::set_auto_dc_offset, + py::arg("enb"), + py::arg("chan") = 0, + D(usrp_source, set_auto_dc_offset)) + + + .def("set_dc_offset", + &usrp_source::set_dc_offset, + py::arg("offset"), + py::arg("chan") = 0, + D(usrp_source, set_dc_offset)) + + + .def("set_auto_iq_balance", + &usrp_source::set_auto_iq_balance, + py::arg("enb"), + py::arg("chan") = 0, + D(usrp_source, set_auto_iq_balance)) + + + .def("set_iq_balance", + &usrp_source::set_iq_balance, + py::arg("correction"), + py::arg("chan") = 0, + D(usrp_source, set_iq_balance)) + + + .def("set_rx_agc", + &usrp_source::set_rx_agc, + py::arg("enable"), + py::arg("chan") = 0, + D(usrp_source, set_rx_agc)) + + + .def("finite_acquisition", + &usrp_source::finite_acquisition, + py::arg("nsamps"), + D(usrp_source, finite_acquisition)) + + + .def("finite_acquisition_v", + &usrp_source::finite_acquisition_v, + py::arg("nsamps"), + D(usrp_source, finite_acquisition_v)) + + ; +} diff --git a/gr-uhd/python/uhd/qa_uhd.py b/gr-uhd/python/uhd/qa_uhd.py index f36a6e9f1d..a954a2233b 100644 --- a/gr-uhd/python/uhd/qa_uhd.py +++ b/gr-uhd/python/uhd/qa_uhd.py @@ -37,6 +37,8 @@ class test_uhd(gr_unittest.TestCase): """ Try to manipulate the stream args channels for proper swig'ing checks. """ + # FIXME: stream_args_t.channels.append does not work due to copy operation of STL vectors + # Needs to either change API, remove QA test, or somehow remap append() sa = uhd.stream_args_t() sa.channels.append(1) sa.channels.append(0) |