Skip to content

Commit f132177

Browse files
committed
Merge 'origin/gen2_uvc' into develop -- #820
2 parents b03248d + 5af35ba commit f132177

File tree

7 files changed

+169
-1
lines changed

7 files changed

+169
-1
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ pybind11_add_module(${TARGET_NAME}
127127
src/pipeline/node/AprilTagBindings.cpp
128128
src/pipeline/node/DetectionParserBindings.cpp
129129
src/pipeline/node/WarpBindings.cpp
130+
src/pipeline/node/UVCBindings.cpp
130131
src/pipeline/node/ToFBindings.cpp
131132

132133
src/pipeline/datatype/ADatatypeBindings.cpp

examples/ColorCamera/rgb_uvc.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
#!/usr/bin/env python3
2+
3+
import time
4+
import argparse
5+
6+
parser = argparse.ArgumentParser()
7+
parser.add_argument('-fb', '--flash-bootloader', default=False, action="store_true")
8+
parser.add_argument('-f', '--flash-app', default=False, action="store_true")
9+
parser.add_argument('-l', '--load-and-exit', default=False, action="store_true")
10+
args = parser.parse_args()
11+
12+
if args.load_and_exit:
13+
import os
14+
# Disabling device watchdog, so it doesn't need the host to ping periodically.
15+
# Note: this is done before importing `depthai`
16+
os.environ["DEPTHAI_WATCHDOG"] = "0"
17+
18+
import depthai as dai
19+
20+
def getPipeline():
21+
enable_4k = True # Will downscale 4K -> 1080p
22+
23+
pipeline = dai.Pipeline()
24+
25+
# Define a source - color camera
26+
cam_rgb = pipeline.createColorCamera()
27+
cam_rgb.setBoardSocket(dai.CameraBoardSocket.CAM_A)
28+
cam_rgb.setInterleaved(False)
29+
#cam_rgb.initialControl.setManualFocus(130)
30+
31+
if enable_4k:
32+
cam_rgb.setResolution(dai.ColorCameraProperties.SensorResolution.THE_4_K)
33+
cam_rgb.setIspScale(1, 2)
34+
else:
35+
cam_rgb.setResolution(dai.ColorCameraProperties.SensorResolution.THE_1080_P)
36+
37+
# Create an UVC (USB Video Class) output node
38+
uvc = pipeline.createUVC()
39+
cam_rgb.video.link(uvc.input)
40+
41+
# Note: if the pipeline is sent later to device (using startPipeline()),
42+
# it is important to pass the device config separately when creating the device
43+
config = dai.Device.Config()
44+
# config.board.uvc = dai.BoardConfig.UVC() # enable default 1920x1080 NV12
45+
config.board.uvc = dai.BoardConfig.UVC(1920, 1080)
46+
config.board.uvc.frameType = dai.ImgFrame.Type.NV12
47+
# config.board.uvc.cameraName = "My Custom Cam"
48+
pipeline.setBoardConfig(config.board)
49+
50+
return pipeline
51+
52+
# Will flash the bootloader if no pipeline is provided as argument
53+
def flash(pipeline=None):
54+
(f, bl) = dai.DeviceBootloader.getFirstAvailableDevice()
55+
bootloader = dai.DeviceBootloader(bl, True)
56+
57+
# Create a progress callback lambda
58+
progress = lambda p : print(f'Flashing progress: {p*100:.1f}%')
59+
60+
startTime = time.monotonic()
61+
if pipeline is None:
62+
print("Flashing bootloader...")
63+
bootloader.flashBootloader(progress)
64+
else:
65+
print("Flashing application pipeline...")
66+
bootloader.flash(progress, pipeline)
67+
68+
elapsedTime = round(time.monotonic() - startTime, 2)
69+
print("Done in", elapsedTime, "seconds")
70+
71+
if args.flash_bootloader or args.flash_app:
72+
if args.flash_bootloader: flash()
73+
if args.flash_app: flash(getPipeline())
74+
print("Flashing successful. Please power-cycle the device")
75+
quit()
76+
77+
if args.load_and_exit:
78+
device = dai.Device(getPipeline())
79+
print("\nDevice started. Attempting to force-terminate this process...")
80+
print("Open an UVC viewer to check the camera stream.")
81+
print("To reconnect with depthai, a device power-cycle may be required in some cases")
82+
# We do not want the device to be closed, so terminate the process uncleanly.
83+
# (TODO add depthai API to be able to cleanly exit without closing device)
84+
import signal
85+
os.kill(os.getpid(), signal.SIGTERM)
86+
87+
# Standard UVC load with depthai
88+
with dai.Device(getPipeline()) as device:
89+
print("\nDevice started, please keep this process running")
90+
print("and open an UVC viewer to check the camera stream.")
91+
print("\nTo close: Ctrl+C")
92+
93+
# Doing nothing here, just keeping the host feeding the watchdog
94+
while True:
95+
try:
96+
time.sleep(0.1)
97+
except KeyboardInterrupt:
98+
break

src/DeviceBindings.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ void DeviceBindings::bind(pybind11::module& m, void* pCallstack){
343343
py::enum_<BoardConfig::GPIO::Pull> boardConfigGpioPull(boardConfigGpio, "Pull", DOC(dai, BoardConfig, GPIO, Pull));
344344
py::enum_<BoardConfig::GPIO::Drive> boardConfigGpioDrive(boardConfigGpio, "Drive", DOC(dai, BoardConfig, GPIO, Drive));
345345
py::class_<BoardConfig::UART> boardConfigUart(boardConfig, "UART", DOC(dai, BoardConfig, UART));
346+
py::class_<BoardConfig::UVC> boardConfigUvc(boardConfig, "UVC", DOC(dai, BoardConfig, UVC));
346347
struct PyClock{};
347348
py::class_<PyClock> clock(m, "Clock");
348349

@@ -379,6 +380,8 @@ void DeviceBindings::bind(pybind11::module& m, void* pCallstack){
379380
.def_readwrite("flashBootedVid", &BoardConfig::USB::flashBootedVid)
380381
.def_readwrite("flashBootedPid", &BoardConfig::USB::flashBootedPid)
381382
.def_readwrite("maxSpeed", &BoardConfig::USB::maxSpeed)
383+
.def_readwrite("productName", &BoardConfig::USB::productName)
384+
.def_readwrite("manufacturer", &BoardConfig::USB::manufacturer)
382385
;
383386

384387
// Bind BoardConfig::Network
@@ -456,6 +459,17 @@ void DeviceBindings::bind(pybind11::module& m, void* pCallstack){
456459
.def_readwrite("tmp", &BoardConfig::UART::tmp)
457460
;
458461

462+
// Bind BoardConfig::UVC
463+
boardConfigUvc
464+
.def(py::init<>())
465+
.def(py::init<uint16_t, uint16_t>())
466+
.def_readwrite("cameraName", &BoardConfig::UVC::cameraName)
467+
.def_readwrite("width", &BoardConfig::UVC::width)
468+
.def_readwrite("height", &BoardConfig::UVC::height)
469+
.def_readwrite("frameType", &BoardConfig::UVC::frameType)
470+
.def_readwrite("enable", &BoardConfig::UVC::enable)
471+
;
472+
459473
// Bind BoardConfig
460474
boardConfig
461475
.def(py::init<>())
@@ -474,6 +488,7 @@ void DeviceBindings::bind(pybind11::module& m, void* pCallstack){
474488
.def_readwrite("logSizeMax", &BoardConfig::logSizeMax, DOC(dai, BoardConfig, logSizeMax))
475489
.def_readwrite("logVerbosity", &BoardConfig::logVerbosity, DOC(dai, BoardConfig, logVerbosity))
476490
.def_readwrite("logDevicePrints", &BoardConfig::logDevicePrints, DOC(dai, BoardConfig, logDevicePrints))
491+
.def_readwrite("uvc", &BoardConfig::uvc, DOC(dai, BoardConfig, uvc))
477492
;
478493

479494
// Bind Device::Config

src/pipeline/PipelineBindings.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "depthai/pipeline/node/FeatureTracker.hpp"
2929
#include "depthai/pipeline/node/AprilTag.hpp"
3030
#include "depthai/pipeline/node/DetectionParser.hpp"
31+
#include "depthai/pipeline/node/UVC.hpp"
3132

3233
// depthai-shared
3334
#include "depthai-shared/properties/GlobalProperties.hpp"
@@ -142,6 +143,7 @@ void PipelineBindings::bind(pybind11::module& m, void* pCallstack){
142143
.def("createFeatureTracker", &Pipeline::create<node::FeatureTracker>)
143144
.def("createAprilTag", &Pipeline::create<node::AprilTag>)
144145
.def("createDetectionParser", &Pipeline::create<node::DetectionParser>)
146+
.def("createUVC", &Pipeline::create<node::UVC>)
145147
;
146148

147149

src/pipeline/node/NodeBindings.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ void bind_edgedetector(pybind11::module& m, void* pCallstack);
114114
void bind_featuretracker(pybind11::module& m, void* pCallstack);
115115
void bind_apriltag(pybind11::module& m, void* pCallstack);
116116
void bind_detectionparser(pybind11::module& m, void* pCallstack);
117+
void bind_uvc(pybind11::module& m, void* pCallstack);
117118
void bind_tof(pybind11::module& m, void* pCallstack);
118119

119120
void NodeBindings::addToCallstack(std::deque<StackFunction>& callstack) {
@@ -144,6 +145,7 @@ void NodeBindings::addToCallstack(std::deque<StackFunction>& callstack) {
144145
callstack.push_front(bind_featuretracker);
145146
callstack.push_front(bind_apriltag);
146147
callstack.push_front(bind_detectionparser);
148+
callstack.push_front(bind_uvc);
147149
callstack.push_front(bind_tof);
148150
}
149151

src/pipeline/node/UVCBindings.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
2+
#include "NodeBindings.hpp"
3+
#include "Common.hpp"
4+
5+
#include "depthai/pipeline/Pipeline.hpp"
6+
#include "depthai/pipeline/Node.hpp"
7+
#include "depthai/pipeline/node/UVC.hpp"
8+
9+
void bind_uvc(pybind11::module& m, void* pCallstack){
10+
11+
using namespace dai;
12+
using namespace dai::node;
13+
14+
// Node and Properties declare upfront
15+
py::class_<UVCProperties> uvcProperties(m, "UVCProperties", DOC(dai, UVCProperties));
16+
auto uvc = ADD_NODE(UVC);
17+
18+
///////////////////////////////////////////////////////////////////////
19+
///////////////////////////////////////////////////////////////////////
20+
///////////////////////////////////////////////////////////////////////
21+
// Call the rest of the type defines, then perform the actual bindings
22+
Callstack* callstack = (Callstack*) pCallstack;
23+
auto cb = callstack->top();
24+
callstack->pop();
25+
cb(m, pCallstack);
26+
// Actual bindings
27+
///////////////////////////////////////////////////////////////////////
28+
///////////////////////////////////////////////////////////////////////
29+
///////////////////////////////////////////////////////////////////////
30+
31+
// Properties
32+
uvcProperties
33+
.def_readwrite("gpioInit", &UVCProperties::gpioInit)
34+
.def_readwrite("gpioStreamOn", &UVCProperties::gpioStreamOn)
35+
.def_readwrite("gpioStreamOff", &UVCProperties::gpioStreamOff)
36+
;
37+
38+
// UVC node
39+
uvc
40+
.def_readonly("input", &UVC::input, DOC(dai, node, UVC, input))
41+
.def("setGpiosOnInit", &UVC::setGpiosOnInit, py::arg("list"), DOC(dai, node, UVC, setGpiosOnInit))
42+
.def("setGpiosOnStreamOn", &UVC::setGpiosOnStreamOn, py::arg("list"), DOC(dai, node, UVC, setGpiosOnStreamOn))
43+
.def("setGpiosOnStreamOff", &UVC::setGpiosOnStreamOff, py::arg("list"), DOC(dai, node, UVC, setGpiosOnStreamOff))
44+
;
45+
46+
// ALIAS
47+
daiNodeModule.attr("UVC").attr("Properties") = uvcProperties;
48+
49+
}
50+

0 commit comments

Comments
 (0)