218 lines
6.5 KiB
YAML
218 lines
6.5 KiB
YAML
api_version: cmvr.edge.ai/v1
|
|
|
|
runtime:
|
|
thread_workers: 3
|
|
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
|
|
# Violation-alert platform HTTP base URL.
|
|
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@1
|
|
# 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 device 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/v1/best.pt
|
|
device: cpu
|
|
imgsz: 640
|
|
iou: 0.70
|
|
half: false
|
|
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
|
|
|
|
alert_platform:
|
|
uses: platform.http_json_sink@1
|
|
with:
|
|
endpoint: ppe_alert_platform
|
|
path: /v1/detection-alerts
|
|
# 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
|
|
|
|
- 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: repeat_gate.alerts
|
|
to: alert_platform.input
|
|
qos:
|
|
profile: telemetry
|
|
capacity: 64
|
|
overflow: block
|
|
|
|
talk:
|
|
enabled: true
|
|
nodes:
|
|
audio_stream_placeholder:
|
|
# Replace with cmvr.grpc.microphone_audio_stream@1 when its proto lands.
|
|
uses: core.sequence_source@1
|
|
with:
|
|
items:
|
|
- simulated-audio-chunk
|
|
schema_name: AudioChunk
|
|
schema_version: 1
|
|
|
|
dialogue_placeholder:
|
|
# The real chain will be VAD -> ASR -> dialogue -> TTS.
|
|
uses: core.passthrough@1
|
|
|
|
output:
|
|
uses: core.log_sink@1
|
|
with:
|
|
logger: cmvr_edge_ai.talk
|
|
|
|
edges:
|
|
- from: audio_stream_placeholder.output
|
|
to: dialogue_placeholder.input
|
|
qos:
|
|
profile: audio_contiguous
|
|
capacity: 16
|
|
overflow: block
|
|
|
|
- from: dialogue_placeholder.output
|
|
to: output.input
|
|
qos:
|
|
profile: request
|
|
capacity: 8
|
|
overflow: block
|