252 lines
8.1 KiB
YAML
252 lines
8.1 KiB
YAML
api_version: cmvr.edge.ai/v1
|
|
|
|
runtime:
|
|
# PyAV plus the PPE and phone-use YOLO branches share this bounded pool.
|
|
thread_workers: 4
|
|
shutdown_timeout_s: 8
|
|
|
|
endpoints:
|
|
cmvr_es:
|
|
transport: grpc
|
|
# cmvr-es gRPC address. Change this value for each deployed robot.
|
|
target: 192.168.0.119:50052
|
|
tls: false
|
|
timeout_s: 5
|
|
options:
|
|
max_receive_mb: 32
|
|
|
|
ppe_alert_platform:
|
|
transport: http
|
|
# Detection-alert platform HTTP base URL. The alert payload model_id and
|
|
# rule_id distinguish PPE violations from phone-use violations.
|
|
base_url: http://192.168.0.222:13080
|
|
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
|
|
# 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,
|
|
# 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
|
|
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
|
|
|
|
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
|
|
|
|
alert_platform:
|
|
uses: platform.http_json_sink@1
|
|
with:
|
|
endpoint: ppe_alert_platform
|
|
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
|
|
# 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
|
|
|
|
# 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
|
|
|
|
- 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
|
|
|
|
- from: repeat_gate.alerts
|
|
to: alert_platform.input
|
|
qos:
|
|
profile: telemetry
|
|
capacity: 64
|
|
overflow: block
|
|
|
|
- from: phone_repeat_gate.alerts
|
|
to: alert_platform.input
|
|
qos:
|
|
profile: telemetry
|
|
capacity: 64
|
|
overflow: block
|