Skip to content

Commit 88f100a

Browse files
authored
Support multiple oakd devices and manual camera controls (#17)
* Support providing mxid to use specific OAKD device * Fix depthai.Device constructor deprecation warnings * Manual camera controls
1 parent 91207c1 commit 88f100a

File tree

1 file changed

+61
-2
lines changed

1 file changed

+61
-2
lines changed

python/cli/record/oak.py

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,15 @@ def define_args(p):
5656
p.add_argument('--map', help='Record SLAM map', action="store_true")
5757
p.add_argument('--no_feature_tracker', help='Disable on-device feature tracking', action="store_true")
5858
p.add_argument('--vio_auto_exposure', help='Enable SpectacularAI auto exposure which optimizes exposure parameters for VIO performance (BETA)', action="store_true")
59+
p.add_argument('--white_balance', help='Set manual camera white balance temperature (K)', type=int)
60+
p.add_argument('--exposure', help='Set manual camera exposure (us)', type=int)
61+
p.add_argument('--sensitivity', help='Set camera sensitivity (iso)', type=int)
5962
p.add_argument('--ir_dot_brightness', help='OAK-D Pro (W) IR laser projector brightness (mA), 0 - 1200', type=float, default=0)
6063
p.add_argument("--resolution", help="Gray input resolution (gray)",
6164
default='400p',
6265
choices=['400p', '800p', '1200p'])
66+
p.add_argument('--mxid', help="Specific OAK-D device's MxID you want to use, if you have multiple devices connected")
67+
p.add_argument('--list_devices', help="List connected OAK-D devices", action="store_true")
6368

6469
return p
6570

@@ -79,6 +84,25 @@ def auto_subfolder(outputFolder):
7984
outputFolder = os.path.join(outputFolder, autoFolderName)
8085
return outputFolder
8186

87+
def list_oakd_devices():
88+
import depthai
89+
print('Searching for all available devices...\n')
90+
infos: List[depthai.DeviceInfo] = depthai.DeviceBootloader.getAllAvailableDevices()
91+
if len(infos) == 0:
92+
print("Couldn't find any available devices.")
93+
return
94+
for info in infos:
95+
with depthai.Device(depthai.Pipeline(), info, depthai.UsbSpeed.SUPER_PLUS) as device:
96+
calib = device.readCalibration()
97+
eeprom = calib.getEepromData()
98+
state = str(info.state).split('X_LINK_')[1] # Converts enum eg. 'XLinkDeviceState.X_LINK_UNBOOTED' to 'UNBOOTED'
99+
print(f"Found device '{info.name}', MxId: '{info.mxid}'")
100+
print(f" State: {state}")
101+
print(f" Product name: {eeprom.productName}")
102+
print(f" Board name: {eeprom.boardName}")
103+
print(f" Camera sensors: {device.getCameraSensorNames()}")
104+
105+
82106
def record(args):
83107
import depthai
84108
import spectacularAI
@@ -88,6 +112,10 @@ def record(args):
88112
import threading
89113
import time
90114

115+
if args.list_devices:
116+
list_oakd_devices()
117+
return
118+
91119
config = spectacularAI.depthai.Configuration()
92120
pipeline = depthai.Pipeline()
93121

@@ -169,12 +197,31 @@ def create_gray_encoder(node, name):
169197
create_gray_encoder(vio_pipeline.stereo.rectifiedLeft, 'left')
170198
create_gray_encoder(vio_pipeline.stereo.rectifiedRight, 'right')
171199

200+
cameraControlQueueNames = []
201+
if args.white_balance or args.exposure or args.sensitivity:
202+
def create_rgb_camera_control(colorCameraNode):
203+
controlName = f"control_{len(cameraControlQueueNames)}"
204+
cameraControlQueueNames.append(controlName)
205+
controlIn = pipeline.create(depthai.node.XLinkIn)
206+
controlIn.setStreamName(controlName)
207+
controlIn.out.link(colorCameraNode.inputControl)
208+
if vio_pipeline.colorLeft: create_rgb_camera_control(vio_pipeline.colorLeft)
209+
if vio_pipeline.colorRight: create_rgb_camera_control(vio_pipeline.colorRight)
210+
if vio_pipeline.monoLeft: create_rgb_camera_control(vio_pipeline.monoLeft)
211+
if vio_pipeline.monoRight: create_rgb_camera_control(vio_pipeline.monoRight)
212+
172213
should_quit = threading.Event()
173214
def main_loop(plotter=None):
174215
frame_number = 1
175216

176-
with depthai.Device(pipeline) as device, \
177-
vio_pipeline.startSession(device) as vio_session:
217+
deviceInfo = None
218+
if args.mxid: deviceInfo = depthai.DeviceInfo(args.mxid)
219+
def createDevice():
220+
if deviceInfo:
221+
return depthai.Device(pipeline, deviceInfo=deviceInfo, maxUsbSpeed=depthai.UsbSpeed.SUPER_PLUS)
222+
return depthai.Device(pipeline)
223+
224+
with createDevice() as device, vio_pipeline.startSession(device) as vio_session:
178225

179226
if args.ir_dot_brightness > 0:
180227
device.setIrLaserDotProjectorBrightness(args.ir_dot_brightness)
@@ -195,6 +242,18 @@ def open_gray_video(name):
195242
videoFile = open(outputFolder + "/rgb_video.h265", "wb")
196243
rgbQueue = device.getOutputQueue(name="h265-rgb", maxSize=30, blocking=False)
197244

245+
if args.white_balance or args.exposure or args.sensitivity:
246+
for controlName in cameraControlQueueNames:
247+
cameraControlQueue = device.getInputQueue(name=controlName)
248+
ctrl = depthai.CameraControl()
249+
if args.exposure or args.sensitivity:
250+
if not (args.exposure and args.sensitivity):
251+
raise Exception("If exposure or sensitivity is given, then both of them must be given")
252+
ctrl.setManualExposure(args.exposure, args.sensitivity)
253+
if args.white_balance:
254+
ctrl.setManualWhiteBalance(args.white_balance)
255+
cameraControlQueue.send(ctrl)
256+
198257
print("Recording to '{0}'".format(config.recordingFolder))
199258
print("")
200259
if plotter is not None:

0 commit comments

Comments
 (0)