diff --git a/depthai-core b/depthai-core index 3df1e1319..8071ddb6c 160000 --- a/depthai-core +++ b/depthai-core @@ -1 +1 @@ -Subproject commit 3df1e13199f72dd830fa46d5e2147bda6de3fea1 +Subproject commit 8071ddb6c4b2228c48c6eca11d0c400c3b3081d4 diff --git a/examples/rgb_preview.py b/examples/rgb_preview.py index 45eea1a10..8484547a9 100755 --- a/examples/rgb_preview.py +++ b/examples/rgb_preview.py @@ -20,9 +20,9 @@ # Linking camRgb.preview.link(xoutRgb.input) -# Connect to device and start pipeline -with dai.Device(pipeline) as device: - +# Connect to the device +with dai.Device(pipeline, dai.UsbSpeed.SUPER) as device: + # Print out available cameras print('Connected cameras: ', device.getConnectedCameras()) # Print out usb speed print('Usb speed: ', device.getUsbSpeed().name) @@ -31,7 +31,7 @@ qRgb = device.getOutputQueue(name="rgb", maxSize=4, blocking=False) while True: - inRgb = qRgb.get() # blocking call, will wait until a new data has arrived + inRgb = qRgb.get() # blocking call, will wait until a new data has arrived # Retrieve 'bgr' (opencv format) frame cv2.imshow("rgb", inRgb.getCvFrame()) diff --git a/src/DeviceBindings.cpp b/src/DeviceBindings.cpp index 3f242a698..58efac9f7 100644 --- a/src/DeviceBindings.cpp +++ b/src/DeviceBindings.cpp @@ -2,6 +2,7 @@ // depthai #include "depthai/device/Device.hpp" +#include "depthai/pipeline/Pipeline.hpp" // std::chrono bindings #include @@ -10,9 +11,10 @@ // hedley #include + // Searches for available devices (as Device constructor) // but pooling, to check for python interrupts, and releases GIL in between -static std::unique_ptr deviceConstructorHelper(const dai::Pipeline& pipeline, const std::string& pathToCmd = "", bool usb2Mode = false){ +static dai::DeviceInfo deviceSearchHelper(){ auto startTime = std::chrono::steady_clock::now(); bool found; dai::DeviceInfo deviceInfo = {}; @@ -40,6 +42,13 @@ static std::unique_ptr deviceConstructorHelper(const dai::Pipeline& // if no devices found, then throw if(!found) throw std::runtime_error("No available devices"); + return deviceInfo; +} + +static std::unique_ptr deviceConstructorHelper(const dai::Pipeline& pipeline, const std::string& pathToCmd = "", bool usb2Mode = false){ + // Find device + dai::DeviceInfo deviceInfo = deviceSearchHelper(); + // Check if pathToCmd supplied if(pathToCmd.empty()){ return std::unique_ptr(new dai::Device(pipeline, deviceInfo, usb2Mode)); @@ -49,35 +58,9 @@ static std::unique_ptr deviceConstructorHelper(const dai::Pipeline& return nullptr; } -// Searches for available devices (as Device constructor) -// but pooling, to check for python interrupts, and releases GIL in between static std::unique_ptr deviceConstructorHelper(dai::OpenVINO::Version version, const std::string& pathToCmd = "", bool usb2Mode = false){ - auto startTime = std::chrono::steady_clock::now(); - bool found; - dai::DeviceInfo deviceInfo = {}; - do { - { - // releases python GIL - py::gil_scoped_release release; - std::tie(found, deviceInfo) = dai::Device::getFirstAvailableDevice(); - // Check if found - if(found){ - break; - } else { - // block for 100ms - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - } - // reacquires python GIL for PyErr_CheckSignals call - // check if interrupt triggered in between - if (PyErr_CheckSignals() != 0) throw py::error_already_set(); - } while(std::chrono::steady_clock::now() - startTime < dai::Device::DEFAULT_SEARCH_TIME); - - // If neither UNBOOTED nor BOOTLOADER were found (after 'DEFAULT_SEARCH_TIME'), try BOOTED - if(!found) std::tie(found, deviceInfo) = dai::XLinkConnection::getFirstDevice(X_LINK_BOOTED); - - // if no devices found, then throw - if(!found) throw std::runtime_error("No available devices"); + // Find device + dai::DeviceInfo deviceInfo = deviceSearchHelper(); // Check if pathToCmd supplied if(pathToCmd.empty()){ @@ -118,6 +101,9 @@ void DeviceBindings::bind(pybind11::module& m, void* pCallstack){ // Type definitions py::class_ device(m, "Device", DOC(dai, Device)); + py::class_ deviceConfig(device, "Config", DOC(dai, Device, Config)); + py::class_ prebootConfig(m, "PrebootConfig", DOC(dai, PrebootConfig)); + py::class_ prebootConfigUsb(prebootConfig, "USB", DOC(dai, PrebootConfig, USB)); /////////////////////////////////////////////////////////////////////// @@ -133,8 +119,31 @@ void DeviceBindings::bind(pybind11::module& m, void* pCallstack){ /////////////////////////////////////////////////////////////////////// + // Bind PrebootConfig::USB + prebootConfigUsb + .def(py::init<>()) + .def_readwrite("vid", &PrebootConfig::USB::vid) + .def_readwrite("pid", &PrebootConfig::USB::pid) + .def_readwrite("flashBootedVid", &PrebootConfig::USB::flashBootedVid) + .def_readwrite("flashBootedPid", &PrebootConfig::USB::flashBootedPid) + .def_readwrite("maxSpeed", &PrebootConfig::USB::maxSpeed) + ; + + // Bind PrebootConfig + prebootConfig + .def(py::init<>()) + .def_readwrite("usb", &PrebootConfig::usb) + .def_readwrite("watchdogTimeoutMs", &PrebootConfig::watchdogTimeoutMs) + ; + + // Bind Device::Config + deviceConfig + .def(py::init<>()) + .def_readwrite("version", &Device::Config::version) + .def_readwrite("preboot", &Device::Config::preboot) + ; - // Bind Device, using DeviceWrapper to be able to destruct the object by calling close() + // Bind device device // Python only methods .def("__enter__", [](py::object obj){ return obj; }) @@ -151,7 +160,7 @@ void DeviceBindings::bind(pybind11::module& m, void* pCallstack){ .def_static("getAnyAvailableDevice", [](){ return Device::getAnyAvailableDevice(); }, DOC(dai, Device, getAnyAvailableDevice, 2)) .def_static("getFirstAvailableDevice", &Device::getFirstAvailableDevice, DOC(dai, Device, getFirstAvailableDevice)) .def_static("getAllAvailableDevices", &Device::getAllAvailableDevices, DOC(dai, Device, getAllAvailableDevices)) - .def_static("getEmbeddedDeviceBinary", &Device::getEmbeddedDeviceBinary, py::arg("usb2Mode"), py::arg("version") = Pipeline::DEFAULT_OPENVINO_VERSION, DOC(dai, Device, getEmbeddedDeviceBinary)) + .def_static("getEmbeddedDeviceBinary", &Device::getEmbeddedDeviceBinary, py::arg("usb2Mode"), py::arg("version") = OpenVINO::DEFAULT_VERSION, DOC(dai, Device, getEmbeddedDeviceBinary)) .def_static("getDeviceByMxId", &Device::getDeviceByMxId, py::arg("mxId"), DOC(dai, Device, getDeviceByMxId)) // methods @@ -162,37 +171,70 @@ void DeviceBindings::bind(pybind11::module& m, void* pCallstack){ // Blocking constructor return deviceConstructorHelper(pipeline, std::string(""), usb2Mode); }), py::arg("pipeline"), py::arg("usb2Mode"), DOC(dai, Device, Device, 2)) + + .def(py::init([](const Pipeline& pipeline, UsbSpeed maxUsbSpeed){ + auto dev = deviceSearchHelper(); + // Blocking constructor + return std::make_unique(pipeline, dev, maxUsbSpeed); + }), py::arg("pipeline"), py::arg("maxUsbSpeed"), DOC(dai, Device, Device, 2)) + .def(py::init([](const Pipeline& pipeline, const std::string& pathToCmd){ // Blocking constructor return deviceConstructorHelper(pipeline, pathToCmd); - }), py::arg("pipeline"), py::arg("pathToCmd"), DOC(dai, Device, Device, 3)) + }), py::arg("pipeline"), py::arg("pathToCmd"), DOC(dai, Device, Device, 4)) .def(py::init([](const Pipeline& pipeline, const DeviceInfo& deviceInfo, bool usb2Mode){ // Non blocking constructor return std::unique_ptr(new Device(pipeline, deviceInfo, usb2Mode)); - }), py::arg("pipeline"), py::arg("deviceDesc"), py::arg("usb2Mode") = false, DOC(dai, Device, Device, 4)) + }), py::arg("pipeline"), py::arg("deviceInfo"), py::arg("usb2Mode") = false, DOC(dai, Device, Device, 5)) + + .def(py::init([](const Pipeline& pipeline, const DeviceInfo& deviceInfo, UsbSpeed maxUsbSpeed){ + // Non blocking constructor + return std::make_unique(pipeline, deviceInfo, maxUsbSpeed); + }), py::arg("pipeline"), py::arg("deviceInfo"), py::arg("maxUsbSpeed"), DOC(dai, Device, Device, 6)) + .def(py::init([](const Pipeline& pipeline, const DeviceInfo& deviceInfo, std::string pathToCmd){ // Non blocking constructor return std::unique_ptr(new Device(pipeline, deviceInfo, pathToCmd)); - }), py::arg("pipeline"), py::arg("deviceDesc"), py::arg("pathToCmd"), DOC(dai, Device, Device, 5)) + }), py::arg("pipeline"), py::arg("deviceInfo"), py::arg("pathToCmd"), DOC(dai, Device, Device, 7)) // Device constructor - OpenVINO version - .def(py::init([](OpenVINO::Version version){ return deviceConstructorHelper(version); }), py::arg("version") = Pipeline::DEFAULT_OPENVINO_VERSION, DOC(dai, Device, Device, 6)) + .def(py::init([](OpenVINO::Version version){ return deviceConstructorHelper(version); }), py::arg("version") = OpenVINO::DEFAULT_VERSION, DOC(dai, Device, Device, 8)) + .def(py::init([](OpenVINO::Version version, bool usb2Mode){ // Blocking constructor return deviceConstructorHelper(version, std::string(""), usb2Mode); - }), py::arg("version"), py::arg("usb2Mode"), DOC(dai, Device, Device, 7)) + }), py::arg("version"), py::arg("usb2Mode"), DOC(dai, Device, Device, 9)) + + .def(py::init([](OpenVINO::Version version, UsbSpeed maxUsbSpeed){ + auto dev = deviceSearchHelper(); + // Non blocking constructor + return std::make_unique(version, dev, maxUsbSpeed); + }), py::arg("version"), py::arg("maxUsbSpeed"), DOC(dai, Device, Device, 10)) + .def(py::init([](OpenVINO::Version version, const std::string& pathToCmd){ // Blocking constructor return deviceConstructorHelper(version, pathToCmd); - }), py::arg("version"), py::arg("pathToCmd"), DOC(dai, Device, Device, 8)) + }), py::arg("version"), py::arg("pathToCmd"), DOC(dai, Device, Device, 11)) .def(py::init([](OpenVINO::Version version, const DeviceInfo& deviceInfo, bool usb2Mode){ // Non blocking constructor return std::unique_ptr(new Device(version, deviceInfo, usb2Mode)); - }), py::arg("version"), py::arg("deviceDesc"), py::arg("usb2Mode") = false, DOC(dai, Device, Device, 9)) + }), py::arg("version"), py::arg("deviceInfo"), py::arg("usb2Mode") = false, DOC(dai, Device, Device, 12)) + + .def(py::init([](OpenVINO::Version version, const DeviceInfo& deviceInfo, UsbSpeed maxUsbSpeed){ + // Non blocking constructor + return std::unique_ptr(new Device(version, deviceInfo, maxUsbSpeed)); + }), py::arg("version"), py::arg("deviceInfo"), py::arg("maxUsbSpeed") = false, DOC(dai, Device, Device, 13)) + + .def(py::init([](OpenVINO::Version version, const DeviceInfo& deviceInfo, std::string pathToCmd){ // Non blocking constructor return std::unique_ptr(new Device(version, deviceInfo, pathToCmd)); - }), py::arg("version"), py::arg("deviceDesc"), py::arg("pathToCmd"), DOC(dai, Device, Device, 10)) + }), py::arg("version"), py::arg("deviceInfo"), py::arg("pathToCmd"), DOC(dai, Device, Device, 14)) + + .def(py::init([](const DeviceInfo& deviceInfo, Device::Config config){ + // Non blocking constructor + return std::make_unique(deviceInfo, config); + }), py::arg("deviceInfo"), py::arg("config"), DOC(dai, Device, Device, 15)) .def("isPipelineRunning", [](Device& d) { py::gil_scoped_release release; return d.isPipelineRunning(); }, DOC(dai, Device, isPipelineRunning)) .def("startPipeline", [](Device& d){ diff --git a/src/pipeline/PipelineBindings.cpp b/src/pipeline/PipelineBindings.cpp index 4583bf9ab..c62f80066 100644 --- a/src/pipeline/PipelineBindings.cpp +++ b/src/pipeline/PipelineBindings.cpp @@ -91,11 +91,13 @@ void PipelineBindings::bind(pybind11::module& m, void* pCallstack){ .def("unlink", &Pipeline::unlink, DOC(dai, Pipeline, unlink), DOC(dai, Pipeline, unlink)) .def("getAssetManager", static_cast(&Pipeline::getAssetManager), py::return_value_policy::reference_internal, DOC(dai, Pipeline, getAssetManager)) .def("getAssetManager", static_cast(&Pipeline::getAssetManager), py::return_value_policy::reference_internal, DOC(dai, Pipeline, getAssetManager)) - .def("setOpenVINOVersion", &Pipeline::setOpenVINOVersion, py::arg("version") = Pipeline::DEFAULT_OPENVINO_VERSION, DOC(dai, Pipeline, setOpenVINOVersion)) + .def("setOpenVINOVersion", &Pipeline::setOpenVINOVersion, py::arg("version") = OpenVINO::DEFAULT_VERSION, DOC(dai, Pipeline, setOpenVINOVersion)) .def("getOpenVINOVersion", &Pipeline::getOpenVINOVersion, DOC(dai, Pipeline, getOpenVINOVersion)) + .def("getRequiredOpenVINOVersion", &Pipeline::getRequiredOpenVINOVersion, DOC(dai, Pipeline, getRequiredOpenVINOVersion)) .def("setCameraTuningBlobPath", &Pipeline::setCameraTuningBlobPath, py::arg("path"), DOC(dai, Pipeline, setCameraTuningBlobPath)) .def("setCalibrationData", &Pipeline::setCalibrationData, py::arg("calibrationDataHandler"), DOC(dai, Pipeline, setCalibrationData)) .def("getCalibrationData", &Pipeline::getCalibrationData, DOC(dai, Pipeline, getCalibrationData)) + .def("getDeviceConfig", &Pipeline::getDeviceConfig, DOC(dai, Pipeline, getDeviceConfig)) // 'Template' create function .def("create", [](dai::Pipeline& p, py::object class_) { auto node = createNode(p, class_);