@@ -119,7 +119,8 @@ def create_yolo(pipeline: dai.Pipeline, camera: dai.node.ColorCamera) -> Tuple[s
119119 yoloDet .input .setBlocking (False )
120120 camera .preview .link (yoloDet .input )
121121 xoutColor = pipeline .createXLinkOut ()
122- passthrough_q_name = f"preview_{ camera .getBoardSocket ()} "
122+ # Match the rest of this script's naming: "preview_<SOCKET_NAME>"
123+ passthrough_q_name = "preview_" + camera .getBoardSocket ().name
123124 xoutColor .setStreamName (passthrough_q_name )
124125 yoloDet .passthrough .link (xoutColor .input )
125126 xout_yolo = pipeline .createXLinkOut ()
@@ -150,6 +151,24 @@ def stress_test(mxid: str = ""):
150151 parser = argparse .ArgumentParser ()
151152 parser .add_argument ("-ne" , "--n-edge-detectors" , default = 0 , type = int , help = "Number of edge detectors to create." )
152153 parser .add_argument ("--no-nnet" , action = "store_true" , default = False , help = "Don't create a neural network." )
154+ parser .add_argument (
155+ "--no-stereo" ,
156+ action = "store_true" ,
157+ default = False ,
158+ help = "Don't create stereo depth (even if a stereo pair is present)." ,
159+ )
160+ parser .add_argument (
161+ "--slow-rampup" ,
162+ action = "store_true" ,
163+ default = False ,
164+ help = "Ramp IR dot/flood brightness after the pipeline starts (helps avoid device crashes)." ,
165+ )
166+ parser .add_argument (
167+ "--rampup-seconds" ,
168+ type = float ,
169+ default = 5.0 ,
170+ help = "Duration (seconds) for --slow-rampup. Recommended: 5." ,
171+ )
153172
154173 # May have some unknown args
155174 args , _ = parser .parse_known_args ()
@@ -159,24 +178,76 @@ def stress_test(mxid: str = ""):
159178 exp_time = 20000
160179
161180 import time
181+
162182 success , device_info = dai .Device .getDeviceByMxId (mxid )
163183 cam_args = [] # Device info or no args at all
164184 if success :
165185 cam_args .append (device_info )
166186 with dai .Device (* cam_args ) as device :
167- print ("Setting default dot intensity to" , dot_intensity )
168- device .setIrLaserDotProjectorIntensity (dot_intensity )
169- print ("Setting default flood intensity to" , flood_intensity )
170- device .setIrFloodLightIntensity (flood_intensity )
187+ if args .slow_rampup :
188+ # Put IR to a known safe baseline before starting the pipeline.
189+ # The actual configured targets are applied after the pipeline is running.
190+ try :
191+ device .setIrLaserDotProjectorIntensity (0.0 )
192+ device .setIrFloodLightIntensity (0.0 )
193+ except Exception as e :
194+ print ("Warning: Failed to set IR intensity baseline:" , repr (e ))
195+ else :
196+ print ("Setting default dot intensity to" , dot_intensity )
197+ device .setIrLaserDotProjectorIntensity (dot_intensity )
198+ print ("Setting default flood intensity to" , flood_intensity )
199+ device .setIrFloodLightIntensity (flood_intensity )
200+
171201 pipeline , outputs , pipeline_context = build_pipeline (device , args )
172202 device .startPipeline (pipeline )
203+
204+ ramp_start_t : Optional [float ] = None
205+ ramp_last_set_t : float = 0.0
206+ ramp_last_dot : Optional [float ] = None
207+ ramp_last_flood : Optional [float ] = None
208+
209+ if args .slow_rampup :
210+ print (
211+ f"Slow rampup enabled: ramping dot={ dot_intensity :.2f} , flood={ flood_intensity :.2f} over { args .rampup_seconds :.1f} s (non-blocking)"
212+ )
213+ ramp_start_t = time .time ()
214+
173215 start_time = time .time ()
174216 queues = [device .getOutputQueue (name , size , False )
175217 for name , size in outputs if name != "sys_log" ]
176218 camera_control_q = device .getInputQueue ("cam_control" )
177219 sys_info_q = device .getOutputQueue ("sys_log" , 1 , False )
178220 usb_speed = device .getUsbSpeed ()
179221 while True :
222+ # Ramp IR on-the-fly while we keep draining queues.
223+ if ramp_start_t is not None :
224+ now = time .time ()
225+ dur = float (args .rampup_seconds )
226+ # Rate-limit device setter calls; these are RPCs and can be chatty.
227+ if dur <= 0 :
228+ frac = 1.0
229+ else :
230+ frac = clamp ((now - ramp_start_t ) / dur , 0.0 , 1.0 )
231+
232+ # Update at most ~20Hz, or on final completion.
233+ if (now - ramp_last_set_t ) >= 0.05 or frac >= 1.0 :
234+ dot = dot_intensity * frac
235+ flood = flood_intensity * frac
236+ try :
237+ if ramp_last_dot is None or abs (dot - ramp_last_dot ) >= 1e-3 :
238+ device .setIrLaserDotProjectorIntensity (dot )
239+ ramp_last_dot = dot
240+ if ramp_last_flood is None or abs (flood - ramp_last_flood ) >= 1e-3 :
241+ device .setIrFloodLightIntensity (flood )
242+ ramp_last_flood = flood
243+ except Exception as e :
244+ print ("Warning: IR rampup failed:" , repr (e ))
245+ ramp_start_t = None
246+ ramp_last_set_t = now
247+
248+ if frac >= 1.0 :
249+ ramp_start_t = None
250+
180251 for queue in queues :
181252 packet = queue .tryGet ()
182253 # print("QUEUE", queue.getName(), "PACKET", packet)
@@ -431,7 +502,7 @@ def build_pipeline(device: dai.Device, args) -> Tuple[dai.Pipeline, List[Tuple[s
431502 edge_detector .outputImage .link (edge_detector_xlink .input )
432503 xlink_outs .append ((stream_name , 5 ))
433504
434- if left and right :
505+ if left and right and not args . no_stereo :
435506 if left .getResolutionWidth () > 1280 :
436507 print ("Left camera width is greater than 1280, setting ISP scale to 2/3" )
437508 left .setIspScale (2 , 3 )
@@ -442,18 +513,19 @@ def build_pipeline(device: dai.Device, args) -> Tuple[dai.Pipeline, List[Tuple[s
442513 output = "out" if hasattr (left , "out" ) else "video"
443514 getattr (left , output ).link (stereo .left )
444515 getattr (right , output ).link (stereo .right )
445- stereo .setDefaultProfilePreset (
446- dai .node .StereoDepth .PresetMode .HIGH_DENSITY )
447- stereo .setOutputSize (left .getResolutionWidth (),
448- left .getResolutionHeight ())
516+ stereo .setDefaultProfilePreset (dai .node .StereoDepth .PresetMode .HIGH_DENSITY )
517+ stereo .setOutputSize (left .getResolutionWidth (), left .getResolutionHeight ())
449518 stereo .setLeftRightCheck (True )
450519 stereo .setSubpixel (True )
451520 stereo .setDepthAlign (align_socket )
452521 else :
453- print ("Device doesn't have a stereo pair, skipping stereo depth creation..." )
522+ if args .no_stereo and left and right :
523+ print ("--no-stereo set, skipping stereo depth creation..." )
524+ else :
525+ print ("Device doesn't have a stereo pair, skipping stereo depth creation..." )
454526 if color_cam is not None :
455527 if not args .no_nnet :
456- if left is not None and right is not None : # Create spatial detection net
528+ if left is not None and right is not None and not args . no_stereo : # Create spatial detection net
457529 print ("Creating spatial detection network..." )
458530 yolo = pipeline .createYoloSpatialDetectionNetwork ()
459531 blob_path = get_or_download_yolo_blob ()
@@ -472,6 +544,15 @@ def build_pipeline(device: dai.Device, args) -> Tuple[dai.Pipeline, List[Tuple[s
472544 color_cam .preview .link (yolo .input )
473545 stereo .depth .link (yolo .inputDepth )
474546
547+ # Always export the color preview stream, even when the color cam is used by the spatial NN
548+ # (otherwise CAM_C looks "missing" since only depth+yolo are published).
549+ passthrough_q_name = "preview_" + color_cam .getBoardSocket ().name
550+ xout_color = pipeline .createXLinkOut ()
551+ xout_color .setStreamName (passthrough_q_name )
552+ yolo .passthrough .link (xout_color .input )
553+ xlink_outs .append ((passthrough_q_name , 4 ))
554+ context .q_name_yolo_passthrough = passthrough_q_name
555+
475556 xout_depth = pipeline .createXLinkOut ()
476557 depth_q_name = "stereo depth"
477558 xout_depth .setStreamName (depth_q_name )
0 commit comments