Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions examples/rgb_preview.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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())
Expand Down
120 changes: 81 additions & 39 deletions src/DeviceBindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

// depthai
#include "depthai/device/Device.hpp"
#include "depthai/pipeline/Pipeline.hpp"

// std::chrono bindings
#include <pybind11/chrono.h>
Expand All @@ -10,9 +11,10 @@
// hedley
#include <hedley/hedley.h>


// Searches for available devices (as Device constructor)
// but pooling, to check for python interrupts, and releases GIL in between
static std::unique_ptr<dai::Device> 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 = {};
Expand Down Expand Up @@ -40,6 +42,13 @@ static std::unique_ptr<dai::Device> 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<dai::Device> 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<dai::Device>(new dai::Device(pipeline, deviceInfo, usb2Mode));
Expand All @@ -49,35 +58,9 @@ static std::unique_ptr<dai::Device> 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<dai::Device> 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()){
Expand Down Expand Up @@ -118,6 +101,9 @@ void DeviceBindings::bind(pybind11::module& m, void* pCallstack){

// Type definitions
py::class_<Device> device(m, "Device", DOC(dai, Device));
py::class_<Device::Config> deviceConfig(device, "Config", DOC(dai, Device, Config));
py::class_<PrebootConfig> prebootConfig(m, "PrebootConfig", DOC(dai, PrebootConfig));
py::class_<PrebootConfig::USB> prebootConfigUsb(prebootConfig, "USB", DOC(dai, PrebootConfig, USB));


///////////////////////////////////////////////////////////////////////
Expand All @@ -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; })
Expand All @@ -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
Expand All @@ -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<Device>(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<Device>(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<Device>(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<Device>(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<Device>(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<Device>(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<Device>(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<Device>(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<Device>(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){
Expand Down
4 changes: 3 additions & 1 deletion src/pipeline/PipelineBindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<const AssetManager& (Pipeline::*)() const>(&Pipeline::getAssetManager), py::return_value_policy::reference_internal, DOC(dai, Pipeline, getAssetManager))
.def("getAssetManager", static_cast<AssetManager& (Pipeline::*)()>(&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_);
Expand Down