Open chengguizi opened 1 year ago
The reproducible code is here https://cdn.discordapp.com/attachments/924798001187274752/1068513158009978930/lack_counting_3cam.py
I also make another attempt, spliting all the controls for each camera, but the same problem persist https://cdn.discordapp.com/attachments/924798001187274752/1068513157460537374/lack_counting_3cam_split.py
I now makes a reproducible code for OAK-D-LR.
By running the script, and press spacebar to pause the sending of control. We can observe that the script node still receives command after we stop sending.
This indicate somewhere along controlQueueA.send(ctrl)
to controlQueueA.send(ctrl)
, message get queued up. Seems no API can control the behaviour of the queue?
controlInA.setMaxDataSize(1)
controlInA.setNumFrames(4)
didn't work
#!/usr/bin/env python3
import cv2
import depthai as dai
pipeline = dai.Pipeline()
#mono camera
monoA= pipeline.create(dai.node.MonoCamera)
monoA.setFps(30)
#ImageManip node. Capability to crop, resize, warp, … incoming image frames
manipA = pipeline.create(dai.node.ImageManip)
#XLinkOut node. Sends messages over XLink.
manipOutA = pipeline.create(dai.node.XLinkOut)
manipOutA.setStreamName("cama")
#mono camera
monoB= pipeline.create(dai.node.MonoCamera)
monoB.setFps(30)
#ImageManip node. Capability to crop, resize, warp, … incoming image frames
manipB = pipeline.create(dai.node.ImageManip)
#XLinkOut node. Sends messages over XLink.
manipOutB = pipeline.create(dai.node.XLinkOut)
manipOutB.setStreamName("camb")
#mono camera
monoC= pipeline.create(dai.node.MonoCamera)
monoC.setFps(30)
#ImageManip node. Capability to crop, resize, warp, … incoming image frames
manipC = pipeline.create(dai.node.ImageManip)
#XLinkOut node. Sends messages over XLink.
manipOutC = pipeline.create(dai.node.XLinkOut)
manipOutC.setStreamName("camc")
#specify which socket using
monoA.setBoardSocket(dai.CameraBoardSocket.CAM_A)
monoA.setResolution(dai.MonoCameraProperties.SensorResolution.THE_1200_P)
monoB.setBoardSocket(dai.CameraBoardSocket.CAM_B)
monoB.setResolution(dai.MonoCameraProperties.SensorResolution.THE_1200_P)
monoC.setBoardSocket(dai.CameraBoardSocket.CAM_C)
monoC.setResolution(dai.MonoCameraProperties.SensorResolution.THE_1200_P)
manipA.setMaxOutputFrameSize(monoA.getResolutionHeight()*monoA.getResolutionWidth()*3)
manipB.setMaxOutputFrameSize(monoB.getResolutionHeight()*monoB.getResolutionWidth()*3)
manipC.setMaxOutputFrameSize(monoC.getResolutionHeight()*monoC.getResolutionWidth()*3)
script = pipeline.create(dai.node.Script)
script.setScript("""
import datetime
while True:
controlIn = node.io['in'].get()
node.warn(f"gotten control at ts = {datetime.datetime.now()}")
node.io['out'].send(controlIn)
""")
#Input for CameraControl message, which can modify camera parameters in runtime
#Linking
#controlXlinkin
controlInA = pipeline.create(dai.node.XLinkIn)
controlInA.setStreamName('controlA')
controlInA.out.link(script.inputs['in'])
script.outputs['out'].link(monoA.inputControl)
script.inputs['in'].setBlocking(False)
script.inputs['in'].setQueueSize(1)
# no effect
controlInA.setMaxDataSize(1)
controlInA.setNumFrames(4)
# no effect
monoA.inputControl.setBlocking(False)
monoA.out.link(manipA.inputImage)
manipA.out.link(manipOutA.input)
monoB.out.link(manipB.inputImage)
manipB.out.link(manipOutB.input)
monoC.out.link(manipC.inputImage)
manipC.out.link(manipOutC.input)
with dai.Device(pipeline) as device:
qA = device.getOutputQueue(manipOutA.getStreamName(), maxSize=4, blocking=False)
qB = device.getOutputQueue(manipOutB.getStreamName(), maxSize=4, blocking=False)
qC = device.getOutputQueue(manipOutC.getStreamName(), maxSize=4, blocking=False)
# maxSize, blocking plays no effect
controlQueueA = device.getInputQueue(controlInA.getStreamName(), maxSize=1, blocking=False)
sensIso=200
expTime_state1=1000
expTime_state2=8000
expTime=1000
frame_lacking=0
#ensure exposure_sent == exposure_received
inA = qA.get()
exposure_received=int(inA.getExposureTime().total_seconds()*1000000)
exposure_sent=exposure_received
paused = False
while True:
if not paused:
inA = qA.get()
exposure_received=int(inA.getExposureTime().total_seconds()*1000000)
#received exposure == sent exposure
if(exposure_received == exposure_sent):
print(f"frame lacking = {frame_lacking}")
#reset
frame_lacking=0
else: #not receiving the sent exposure
frame_lacking+=1
#display image
cv2.imshow("camA", inA.getCvFrame())
key = cv2.waitKey(1)
if key == ord(' '):
paused = not paused
if paused:
print("paused")
else:
print("continue")
if paused:
continue
if(expTime==expTime_state1 and (exposure_received==exposure_sent)): #at stage 1 and received the sent exposure
#send command to change to another state
expTime=expTime_state2
exposure_sent=expTime
ctrl = dai.CameraControl()
ctrl.setManualExposure(expTime, sensIso)
print("Setting manual exposure, time:", expTime, "iso:", sensIso)
controlQueueA.send(ctrl)
elif(expTime==expTime_state2 and (exposure_received==exposure_sent)): #at stage 2 and received the sent exposure
#send command to change to another state
expTime=expTime_state1
exposure_sent=expTime
ctrl = dai.CameraControl()
ctrl.setManualExposure(expTime, sensIso)
print("Setting manual exposure, time:", expTime, "iso:", sensIso)
controlQueueA.send(ctrl)
else:
controlQueueA.send(ctrl)
In the past I've had a lot of trouble with sending control commands to multiple cameras. Setting controls before the camera has started streaming, and even within the first few frames, can be a problem. I wait to send commands until after 10 frames have arrived, per camera. Probably unnecessary, but I queue all commands in a thread-safe queue, and process all pending commands in a grabbing thread.
Describe the bug A clear and concise description of what the bug is.
Minimal Reproducible Example
I will attached the reproducible code in the next reply.
Expected behavior
The key action I would like to take is the following:
Which means, I would like to control all cameras together.
By right, the latency of the control should not be affected by how many
inputControl
i have tied to thecontrolIn
. But what I observe:Screenshots
Behaviour when multiple inputControl from different cameras are tied together
Exponential delays showed up