145 lines
4.0 KiB
YAML
145 lines
4.0 KiB
YAML
api_version: cmvr.edge.ai/v1
|
|
|
|
runtime:
|
|
# Decoder, two YOLO models and viewer drawing share this bounded pool.
|
|
thread_workers: 4
|
|
shutdown_timeout_s: 8
|
|
|
|
endpoints:
|
|
cmvr_es:
|
|
transport: grpc
|
|
# Remote cmvr-es address. Keep this aligned with the robot being viewed.
|
|
target: 192.168.0.119:50052
|
|
tls: false
|
|
timeout_s: 5
|
|
options:
|
|
max_receive_mb: 32
|
|
|
|
pipelines:
|
|
detection_show:
|
|
enabled: true
|
|
nodes:
|
|
camera:
|
|
uses: cmvr.grpc.camera_rgb_stream@1
|
|
with:
|
|
endpoint: cmvr_es
|
|
device_id: wrist_cam
|
|
pixel_format: BGR8
|
|
reconnect: true
|
|
reconnect_initial_s: 0.5
|
|
reconnect_max_s: 10
|
|
stream_log_interval_s: 5
|
|
|
|
decoder:
|
|
uses: media.video_decoder.pyav@1
|
|
|
|
frame_fanout:
|
|
# One shared fan-out node chooses the latest decoded frame before both
|
|
# blocking detector queues. This keeps the two model inputs identical.
|
|
uses: core.passthrough@1
|
|
|
|
detector:
|
|
uses: detection.model@1
|
|
with:
|
|
model: construction-ppe-yolov8@1
|
|
detect_labels:
|
|
- No-Boots
|
|
- No-Ear-Protection
|
|
- No-Glass
|
|
- No-Glove
|
|
- No-Helmet
|
|
- No-Mask
|
|
- No-Vest
|
|
confidence: 0.50
|
|
inference_log_interval_s: 5
|
|
# Required so the viewer receives the exact decoded inference frame.
|
|
attach_frame: true
|
|
model_options:
|
|
# Repository-relative path; launch the viewer from the repository root.
|
|
weights: models/detection/construction-ppe-yolov8/v1/best.pt
|
|
device: cpu
|
|
imgsz: 640
|
|
iou: 0.70
|
|
half: false
|
|
max_det: 100
|
|
|
|
phone_detector:
|
|
uses: detection.model@1
|
|
with:
|
|
model: yolov8n-mobile-phone@1
|
|
detect_labels:
|
|
- mobile_phone
|
|
confidence: 0.50
|
|
inference_log_interval_s: 5
|
|
attach_frame: true
|
|
model_options:
|
|
weights: models/detection/yolov8n-mobile-phone/yolov8n-mobile-phone.pt
|
|
device: cpu
|
|
imgsz: 640
|
|
iou: 0.70
|
|
half: false
|
|
max_det: 100
|
|
|
|
viewer:
|
|
uses: demo.opencv_detection_viewer@1
|
|
with:
|
|
window_name: CMVR PPE + Phone Detection
|
|
window_width: 1280
|
|
window_height: 720
|
|
wait_key_ms: 1
|
|
box_thickness: 2
|
|
font_scale: 0.6
|
|
show_stats: true
|
|
# Render only after both results for the exact same ImageFrame arrive.
|
|
expected_inputs: [ppe, phone]
|
|
max_pending_frames: 8
|
|
|
|
edges:
|
|
# H264/H265 packets must remain contiguous until decoding.
|
|
- from: camera.frames
|
|
to: decoder.frames
|
|
qos:
|
|
profile: video_contiguous
|
|
capacity: 8
|
|
overflow: block
|
|
|
|
# Drop only before the shared fan-out, so both models see the same
|
|
# surviving decoded frame rather than independently dropping frames.
|
|
- from: decoder.frames
|
|
to: frame_fanout.input
|
|
qos:
|
|
profile: realtime_latest
|
|
capacity: 1
|
|
overflow: drop_oldest
|
|
|
|
# These two blocking edges preserve the same frame set and ordering for
|
|
# both models. Do not add independent detector max_fps limits here.
|
|
- from: frame_fanout.output
|
|
to: detector.frames
|
|
qos:
|
|
profile: telemetry
|
|
capacity: 1
|
|
overflow: block
|
|
|
|
- from: frame_fanout.output
|
|
to: phone_detector.frames
|
|
qos:
|
|
profile: telemetry
|
|
capacity: 1
|
|
overflow: block
|
|
|
|
# The viewer joins both result streams by frame identity before drawing.
|
|
- from: detector.detections
|
|
to: viewer.ppe
|
|
qos:
|
|
profile: telemetry
|
|
capacity: 2
|
|
overflow: block
|
|
|
|
- from: phone_detector.detections
|
|
to: viewer.phone
|
|
qos:
|
|
profile: telemetry
|
|
capacity: 2
|
|
overflow: block
|