summaryrefslogtreecommitdiff
path: root/gr-uhd/python/uhd
diff options
context:
space:
mode:
Diffstat (limited to 'gr-uhd/python/uhd')
-rw-r--r--gr-uhd/python/uhd/__init__.py63
-rw-r--r--gr-uhd/python/uhd/bindings/CMakeLists.txt1
-rw-r--r--gr-uhd/python/uhd/bindings/python_bindings.cc9
-rw-r--r--gr-uhd/python/uhd/bindings/uhd_types_python.cc155
-rw-r--r--gr-uhd/python/uhd/bindings/usrp_sink_python.cc22
-rw-r--r--gr-uhd/python/uhd/bindings/usrp_source_python.cc22
6 files changed, 210 insertions, 62 deletions
diff --git a/gr-uhd/python/uhd/__init__.py b/gr-uhd/python/uhd/__init__.py
index 3f24d98826..85a8f2c142 100644
--- a/gr-uhd/python/uhd/__init__.py
+++ b/gr-uhd/python/uhd/__init__.py
@@ -31,39 +31,23 @@ def _prepare_uhd_python():
from . import uhd_python
#some useful typedefs for the user
- # 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)
+ setattr(uhd_python, 'freq_range_t', uhd_python.meta_range_t)
+ setattr(uhd_python, 'gain_range_t', uhd_python.meta_range_t)
#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.types.TuneRequest): #, float):
- def __new__(self, *args, **kwargs): return float.__new__(self)
+ class tune_request_t(uhd_python.tune_request_t):
+ # 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)
+ super().__init__(*args)
for key, val in list(kwargs.items()): setattr(self, key, val)
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.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)
- def __init__(self, *args, **kwargs):
- 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_python, 'device_addr_t', device_addr_t)
-
#make the streamer args take **kwargs on init
- class stream_args_t(uhd.usrp.StreamArgs):
+ class stream_args_t(uhd_python.stream_args_t):
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
@@ -76,12 +60,11 @@ def _prepare_uhd_python():
if key == 'channels':
for v in val: self.channels.append(v)
elif key == 'args':
- self.args = device_addr_t(val)
+ self.args = uhd_python.device_addr_t(val)
else: setattr(self, key, val)
# 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
@@ -104,38 +87,6 @@ def _prepare_uhd_python():
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'):
- def constructor_factory(old_constructor):
- def constructor_interceptor(*args, **kwargs):
- args = list(args)
- kwargs = dict(kwargs)
- for index, key, cast in (
- (0, 'device_addr', device_addr),
- ):
- if len(args) > index:
- args[index] = cast(args[index])
- if key in kwargs:
- kwargs[key] = cast(kwargs[key])
- #don't pass kwargs, it confuses swig, map into args list:
- for key in ('device_addr', 'stream_args',
- 'issue_stream_cmd_on_start', 'tsb_tag_name', 'msgq'):
- if key in kwargs: args.append(kwargs[key])
- return old_constructor(*args)
- return constructor_interceptor
- 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
- #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 pybind
########################################################################
diff --git a/gr-uhd/python/uhd/bindings/CMakeLists.txt b/gr-uhd/python/uhd/bindings/CMakeLists.txt
index 880885462d..8d123da16c 100644
--- a/gr-uhd/python/uhd/bindings/CMakeLists.txt
+++ b/gr-uhd/python/uhd/bindings/CMakeLists.txt
@@ -5,6 +5,7 @@ include(GrPybind)
########################################################################
list(APPEND uhd_python_files
+ uhd_types_python.cc
amsg_source_python.cc
usrp_block_python.cc
usrp_sink_python.cc
diff --git a/gr-uhd/python/uhd/bindings/python_bindings.cc b/gr-uhd/python/uhd/bindings/python_bindings.cc
index eeb7c6e430..e32d1b48cc 100644
--- a/gr-uhd/python/uhd/bindings/python_bindings.cc
+++ b/gr-uhd/python/uhd/bindings/python_bindings.cc
@@ -13,8 +13,11 @@
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <numpy/arrayobject.h>
+#include <uhd/version.hpp>
+
namespace py = pybind11;
+void bind_uhd_types(py::module&);
void bind_amsg_source(py::module&);
void bind_usrp_block(py::module&);
void bind_usrp_sink(py::module&);
@@ -39,8 +42,14 @@ PYBIND11_MODULE(uhd_python, m)
// Allow access to base block methods
py::module::import("gnuradio.gr");
+ bind_uhd_types(m);
bind_amsg_source(m);
bind_usrp_block(m);
bind_usrp_sink(m);
bind_usrp_source(m);
+
+ m.def(
+ "get_version_string",
+ []() { return ::uhd::get_version_string(); },
+ "Returns UHD Version String");
}
diff --git a/gr-uhd/python/uhd/bindings/uhd_types_python.cc b/gr-uhd/python/uhd/bindings/uhd_types_python.cc
new file mode 100644
index 0000000000..fc4cfb86f2
--- /dev/null
+++ b/gr-uhd/python/uhd/bindings/uhd_types_python.cc
@@ -0,0 +1,155 @@
+/*
+ * 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/operators.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+namespace py = pybind11;
+
+#include <gnuradio/uhd/uhd_types.h>
+
+void bind_uhd_types(py::module& m)
+{
+ // Bindings copied from UHD
+
+ using str_map = std::map<std::string, std::string>;
+
+ py::class_<::uhd::device_addr_t>(m, "device_addr_t")
+ // Constructors
+ .def(py::init<>())
+ .def(py::init<std::string>())
+ .def(py::init<str_map>())
+
+ // Methods
+ .def("__str__", &uhd::device_addr_t::to_pp_string)
+ .def("to_string", &uhd::device_addr_t::to_string)
+ .def("to_pp_string", &uhd::device_addr_t::to_pp_string);
+
+ // This will allow functions in Python that take a device_addr to also take
+ // a string:
+ py::implicitly_convertible<std::string, uhd::device_addr_t>();
+
+ using stream_args_t = ::uhd::stream_args_t;
+ py::class_<stream_args_t>(m, "stream_args_t")
+ .def(py::init<const std::string&, const std::string&>())
+ // Properties
+ .def_readwrite("cpu_format", &stream_args_t::cpu_format)
+ .def_readwrite("otw_format", &stream_args_t::otw_format)
+ .def_readwrite("args", &stream_args_t::args)
+ .def_readwrite("channels", &stream_args_t::channels);
+
+
+ // ::uhd::time_spec_t
+ using time_spec_t = ::uhd::time_spec_t;
+
+ py::class_<time_spec_t>(m, "time_spec_t")
+ // Additional constructors
+ .def(py::init<double>())
+ .def(py::init<int64_t, double>())
+ .def(py::init<int64_t, long, double>())
+
+ // Methods
+ .def_static("from_ticks", &time_spec_t::from_ticks)
+
+ .def("get_tick_count", &time_spec_t::get_tick_count)
+ .def("to_ticks", &time_spec_t::to_ticks)
+ .def("get_real_secs", &time_spec_t::get_real_secs)
+ .def("get_full_secs", &time_spec_t::get_full_secs)
+ .def("get_frac_secs", &time_spec_t::get_frac_secs)
+
+ .def(py::self += time_spec_t())
+ .def(py::self -= time_spec_t())
+ .def(py::self + time_spec_t())
+ .def(py::self - time_spec_t())
+ .def(py::self += double())
+ .def(py::self -= double())
+ .def(py::self + double())
+ .def(py::self - double());
+
+ // ::uhd::stream_cmd_t
+ using stream_cmd_t = ::uhd::stream_cmd_t;
+ py::class_<stream_cmd_t>(m, "stream_cmd_t")
+ .def(py::init<stream_cmd_t::stream_mode_t>())
+ // Properties
+ .def_readwrite("num_samps", &stream_cmd_t::num_samps)
+ .def_readwrite("time_spec", &stream_cmd_t::time_spec)
+ .def_readwrite("stream_now", &stream_cmd_t::stream_now);
+
+ // ::uhd::meta_range_t
+ using meta_range_t = ::uhd::meta_range_t;
+
+ py::class_<meta_range_t>(m, "meta_range_t")
+ // Constructors
+ .def(py::init<>())
+ .def(py::init<double, double>())
+ .def(py::init<double, double, double>())
+
+ // Methods
+ .def("start", &meta_range_t::start)
+ .def("stop", &meta_range_t::stop)
+ .def("step", &meta_range_t::step)
+ .def("clip", &meta_range_t::clip, py::arg("value"), py::arg("clip_step") = false)
+ .def("__str__", &meta_range_t::to_pp_string);
+
+ // ::uhd::tune_result_t
+ using tune_result_t = ::uhd::tune_result_t;
+ py::class_<tune_result_t>(m, "tune_result_t")
+ .def(py::init<>())
+ .def_readwrite("clipped_rf_freq", &tune_result_t::clipped_rf_freq)
+ .def_readwrite("target_rf_freq", &tune_result_t::target_rf_freq)
+ .def_readwrite("actual_rf_freq", &tune_result_t::actual_rf_freq)
+ .def_readwrite("target_dsp_freq", &tune_result_t::target_dsp_freq)
+ .def_readwrite("actual_dsp_freq", &tune_result_t::actual_dsp_freq)
+ .def("__str__", &tune_result_t::to_pp_string);
+
+ // ::uhd::tune_request_t
+ using tune_request_t = ::uhd::tune_request_t;
+ py::class_<tune_request_t>(m, "tune_request_t")
+ .def(py::init<double, double>())
+ .def(py::init<double>(), py::arg("target_freq") = 0.0)
+ .def_readwrite("target_freq", &tune_request_t::target_freq)
+ .def_readwrite("rf_freq_policy", &tune_request_t::rf_freq_policy)
+ .def_readwrite("dsp_freq_policy", &tune_request_t::dsp_freq_policy)
+ .def_readwrite("rf_freq", &tune_request_t::rf_freq)
+ .def_readwrite("dsp_freq", &tune_request_t::dsp_freq)
+ .def_readwrite("args", &tune_request_t::args);
+
+
+ // ::uhd::sensor_value_t
+ using sensor_value_t = uhd::sensor_value_t;
+
+ py::class_<sensor_value_t>(m, "sensor_value_t")
+ // Constructors
+ .def(py::init<const std::string&, bool, const std::string&, const std::string&>())
+ .def(py::init<const std::string&,
+ signed,
+ const std::string&,
+ const std::string&>())
+ .def(py::init<const std::string&,
+ double,
+ const std::string&,
+ const std::string&>())
+ .def(py::init<const std::string&, const std::string&, const std::string&>())
+
+ // Methods
+ .def("to_bool", &sensor_value_t::to_bool)
+ .def("to_int", &sensor_value_t::to_int)
+ .def("to_real", &sensor_value_t::to_real)
+ .def("__str__", &sensor_value_t::to_pp_string)
+
+ // Properties
+ .def_readwrite("name", &sensor_value_t::name)
+ .def_readwrite("value", &sensor_value_t::value)
+ .def_readwrite("unit", &sensor_value_t::unit)
+ .def_readwrite("type", &sensor_value_t::type);
+}
diff --git a/gr-uhd/python/uhd/bindings/usrp_sink_python.cc b/gr-uhd/python/uhd/bindings/usrp_sink_python.cc
index bbc8ee0fe4..d0a7dc482d 100644
--- a/gr-uhd/python/uhd/bindings/usrp_sink_python.cc
+++ b/gr-uhd/python/uhd/bindings/usrp_sink_python.cc
@@ -25,10 +25,26 @@ 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))
+ py::class_<usrp_sink,
+ gr::uhd::usrp_block,
+ gr::sync_block,
+ gr::block,
+ gr::basic_block,
+ std::shared_ptr<usrp_sink>>(m, "usrp_sink", D(usrp_sink))
+
+ .def(py::init((std::shared_ptr<gr::uhd::usrp_sink>(*)(const ::uhd::device_addr_t&,
+ const ::uhd::stream_args_t&,
+ const std::string&)) &
+ usrp_sink::make),
+ py::arg("device_addr"),
+ py::arg("stream_args"),
+ py::arg("tsb_tag_name") = "",
+ D(usrp_sink, make))
- .def(py::init(&usrp_sink::make),
+ .def(py::init((std::shared_ptr<gr::uhd::usrp_sink>(*)(const std::string&,
+ const ::uhd::stream_args_t&,
+ const std::string&)) &
+ usrp_sink::make),
py::arg("device_addr"),
py::arg("stream_args"),
py::arg("tsb_tag_name") = "",
diff --git a/gr-uhd/python/uhd/bindings/usrp_source_python.cc b/gr-uhd/python/uhd/bindings/usrp_source_python.cc
index 6834e23cd8..19f3d6017d 100644
--- a/gr-uhd/python/uhd/bindings/usrp_source_python.cc
+++ b/gr-uhd/python/uhd/bindings/usrp_source_python.cc
@@ -25,10 +25,26 @@ 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))
+ py::class_<usrp_source,
+ gr::uhd::usrp_block,
+ gr::sync_block,
+ gr::block,
+ gr::basic_block,
+ std::shared_ptr<usrp_source>>(m, "usrp_source", D(usrp_source))
+
+ .def(py::init(
+ (std::shared_ptr<gr::uhd::usrp_source>(*)(const ::uhd::device_addr_t&,
+ const ::uhd::stream_args_t&,
+ const bool)) &
+ usrp_source::make),
+ py::arg("device_addr"),
+ py::arg("stream_args"),
+ py::arg("issue_stream_cmd_on_start") = true,
+ D(usrp_source, make))
- .def(py::init(&usrp_source::make),
+ .def(py::init((std::shared_ptr<gr::uhd::usrp_source>(*)(
+ const std::string&, const ::uhd::stream_args_t&, const bool)) &
+ usrp_source::make),
py::arg("device_addr"),
py::arg("stream_args"),
py::arg("issue_stream_cmd_on_start") = true,