summaryrefslogtreecommitdiff
path: root/gr-uhd/python/uhd/bindings
diff options
context:
space:
mode:
authorJosh Morman <mormjb@gmail.com>2020-06-10 10:30:12 -0400
committerJosh Morman <mormjb@gmail.com>2020-06-10 13:26:30 -0400
commit0f7369481c40f4b841de8d4f6eca825e7e7b4bda (patch)
tree4498000e906a58639a0bd3a5243ba74ea85d91f9 /gr-uhd/python/uhd/bindings
parent868ec8eecaa1d06696bc072bcf5db300d00da130 (diff)
uhd: fix pybind11 bindings
Instead of relying on the pyuhd pybind11 bindings, create new gr::uhd pybind11 bindings that wrap the underlying types. Trying to use the pyuhd bindings directly has many issues Also, push some of the overloading into the constructors as opposed to in the __init__ functions with constructor interception
Diffstat (limited to 'gr-uhd/python/uhd/bindings')
-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
5 files changed, 203 insertions, 6 deletions
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,