cmvr_edge_ai/configs/active_detection.yaml

252 lines
8.1 KiB
YAML
Raw Normal View History

2026-07-20 16:59:37 +08:00
api_version: cmvr.edge.ai/v1
runtime:
2026-07-21 16:23:33 +08:00
# PyAV plus the PPE and phone-use YOLO branches share this bounded pool.
thread_workers: 4
2026-07-20 16:59:37 +08:00
shutdown_timeout_s: 8
endpoints:
cmvr_es:
transport: grpc
# cmvr-es gRPC address. Change this value for each deployed robot.
2026-07-21 12:07:12 +08:00
target: 192.168.0.119:50052
2026-07-20 16:59:37 +08:00
tls: false
timeout_s: 5
options:
2026-07-20 16:59:37 +08:00
max_receive_mb: 32
2026-07-21 12:07:12 +08:00
ppe_alert_platform:
2026-07-20 16:59:37 +08:00
transport: http
2026-07-21 16:23:33 +08:00
# Detection-alert platform HTTP base URL. The alert payload model_id and
# rule_id distinguish PPE violations from phone-use violations.
2026-07-21 12:07:12 +08:00
base_url: http://192.168.0.222:13080
2026-07-20 16:59:37 +08:00
timeout_s: 3
pipelines:
detection:
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
# Log stream state immediately on first frame and emit a periodic
# progress/stall heartbeat without printing every encoded frame.
stream_log_interval_s: 5
decoder:
uses: media.video_decoder.pyav@1
detector:
uses: detection.model@1
with:
model: construction-ppe-yolov8@2
2026-07-20 16:59:37 +08:00
# Omitting detect_labels means all registered labels. This example
# asks the backend to return only PPE violations used by the rules.
detect_labels:
- No-Boots
- No-Ear-Protection
- No-Glass
- No-Glove
- No-Helmet
- No-Mask
- No-Vest
confidence: 0.50
max_fps: 10
# Log the first completed inference immediately, then aggregate one
# heartbeat every 5 seconds so model activity is visible without
# printing every frame. Set to 1 for one-second debugging, or omit to disable.
inference_log_interval_s: 5
# Keep the decoded threshold frame available to repeat_gate so an
# annotated alert image can be rendered only when a rule triggers.
attach_frame: true
model_options:
# Model artifact and inference provider are deployment configuration,
2026-07-21 12:07:12 +08:00
# not process environment requirements. This repository-relative
# path requires launching cmvr-edge-ai from the repository root.
weights: models/detection/construction-ppe-yolov8/v2/model.onnx
providers: [CPUExecutionProvider]
intra_op_threads: 1
inter_op_threads: 1
2026-07-20 16:59:37 +08:00
imgsz: 640
iou: 0.70
max_det: 100
repeat_gate:
uses: detection.repeat_gate@1
with:
# cmvr-es currently omits capture timestamps on successful stream
# frames, so received time is the deterministic deployment default.
time_source: received
alert_image:
enabled: true
jpeg_quality: 85
rules:
- id: no-boots
labels: [No-Boots]
min_hits: 3
window_ms: 2000
cooldown_ms: 30000
min_confidence: 0.50
scope: source
- id: no-ear-protection
labels: [No-Ear-Protection]
min_hits: 3
window_ms: 2000
cooldown_ms: 30000
min_confidence: 0.50
scope: source
- id: no-glass
labels: [No-Glass]
min_hits: 3
window_ms: 2000
cooldown_ms: 30000
min_confidence: 0.50
scope: source
- id: no-glove
labels: [No-Glove]
min_hits: 3
window_ms: 2000
cooldown_ms: 30000
min_confidence: 0.50
scope: source
- id: no-helmet
labels: [No-Helmet]
min_hits: 3
window_ms: 2000
cooldown_ms: 30000
min_confidence: 0.50
scope: source
- id: no-mask
labels: [No-Mask]
min_hits: 3
window_ms: 2000
cooldown_ms: 30000
min_confidence: 0.50
scope: source
- id: no-vest
labels: [No-Vest]
min_hits: 3
window_ms: 2000
cooldown_ms: 30000
min_confidence: 0.50
scope: source
phone_detector:
uses: detection.model@1
with:
model: people-talking-yolov8x@2
# The source model also contains a generic class named "label". It is
# retained in model registration for class-ID safety but is not an
# actionable phone-use event, so this branch selects only class 1.
detect_labels:
- talking on phone
confidence: 0.50
# YOLOv8x is substantially heavier than the PPE model. Start with a
# conservative CPU rate and tune only after measuring target hardware.
max_fps: 5
inference_log_interval_s: 5
attach_frame: true
model_options:
weights: models/detection/people-talking-yolov8x/v2/model.onnx
providers: [CPUExecutionProvider]
intra_op_threads: 1
inter_op_threads: 1
imgsz: 640
iou: 0.70
max_det: 100
2026-07-21 16:23:33 +08:00
phone_repeat_gate:
uses: detection.repeat_gate@1
with:
time_source: received
alert_image:
enabled: true
jpeg_quality: 85
rules:
- id: talking-on-phone
labels: [talking on phone]
min_hits: 3
window_ms: 2000
cooldown_ms: 30000
min_confidence: 0.50
scope: source
2026-07-21 16:23:33 +08:00
2026-07-21 12:07:12 +08:00
alert_platform:
2026-07-20 16:59:37 +08:00
uses: platform.http_json_sink@1
with:
2026-07-21 12:07:12 +08:00
endpoint: ppe_alert_platform
2026-07-20 16:59:37 +08:00
path: /v1/detection-alerts
# Include the IP from endpoints.cmvr_es.target in every platform
# report so the platform can identify the originating edge device.
grpc_endpoint: cmvr_es
2026-07-20 16:59:37 +08:00
# Platform outages must not stop camera capture or inference. After
# bounded retries, log a WARNING and drop only this report.
failure_mode: log_and_drop
max_attempts: 3
retry_initial_s: 0.25
retry_max_s: 2
edges:
# Encoded H264/H265 packets must remain contiguous before decode.
- from: camera.frames
to: decoder.frames
qos:
profile: video_contiguous
capacity: 8
overflow: block
# Once frames are decoded, keeping only the newest frame bounds latency.
- from: decoder.frames
to: detector.frames
qos:
profile: realtime_latest
capacity: 1
overflow: drop_oldest
2026-07-21 16:23:33 +08:00
# Fan out the already decoded image; do not open a second camera stream
# or decode the same H264/H265 packet twice.
- from: decoder.frames
to: phone_detector.frames
qos:
profile: realtime_latest
capacity: 1
overflow: drop_oldest
2026-07-20 16:59:37 +08:00
- from: detector.detections
to: repeat_gate.detections
qos:
profile: telemetry
# DetectionResult carries a decoded frame when attach_frame is enabled;
# keep this queue short so raw image buffers cannot accumulate. Under
# sustained overload drop_oldest also means dropped results do not count.
capacity: 2
overflow: drop_oldest
- from: phone_detector.detections
to: phone_repeat_gate.detections
qos:
profile: telemetry
# attach_frame carries the decoded image until the rule is evaluated.
capacity: 2
overflow: drop_oldest
2026-07-21 16:23:33 +08:00
2026-07-20 16:59:37 +08:00
- from: repeat_gate.alerts
2026-07-21 12:07:12 +08:00
to: alert_platform.input
2026-07-20 16:59:37 +08:00
qos:
profile: telemetry
capacity: 64
overflow: block
2026-07-21 12:07:12 +08:00
- from: phone_repeat_gate.alerts
to: alert_platform.input
2026-07-21 12:07:12 +08:00
qos:
profile: telemetry
capacity: 64
2026-07-21 12:07:12 +08:00
overflow: block