跳到主要内容

运行时集成

Vision Studio 视觉程序以异步 Job 方式集成到 PLC 运行时中,通过 RuntimeResourcePolicy 管理资源,通过 PLC 变量交换结果数据。

异步执行模型

Job 生命周期

┌──────────┐   触发     ┌──────────┐   调度     ┌──────────┐
│ PLC 扫描 │ ───────→ │ Job 队列 │ ───────→ │ 视觉执行器 │
│ 周期 │ │ (FIFO) │ │ (异步) │
└──────────┘ └──────────┘ └──────┬───┘

┌──────────────────────────────┘


┌────────────────┐
│ 相机采集 │
│ 图像预处理 │
│ 模型推理 │
│ 后处理 │
│ 结果回写 │
└────────┬───────┘


┌────────────────┐
│ PLC 变量状态 │
│ VIS_JOB_DONE │
│ VIS_RESULT_* │
└────────────────┘

Job 状态机

         ┌──────────┐
│ IDLE │ ←── PLC 就绪
└────┬─────┘
│ 触发 (VIS_JOB_START ↑)

┌──────────┐
│ QUEUED │ ←── 排队等待资源
└────┬─────┘
│ 资源就绪

┌──────────┐
│ RUNNING │ ←── 执行中
└────┬─────┘

┌────────┼────────┐
▼ ▼ ▼
┌────────┐┌────────┐┌──────────┐
│DONE ││FAULT ││TIMEOUT │
│(成功) ││(故障) ││(超时) │
└────────┘└────────┘└──────────┘

异步执行的优势

特性同步执行异步 Job
扫描周期影响阻塞,周期延长无影响
推理延迟等待推理完成并行执行
多任务并发不支持支持多 Job 并发
故障处理可能影响 PLC 运行独立故障隔离
资源管理RuntimeResourcePolicy 控制

资源管理 (RuntimeResourcePolicy)

RuntimeResourcePolicy 管理视觉运行时使用的计算资源,确保视觉推理不影响 PLC 核心任务的实时性。

策略配置

{
"vision": {
"runtime_resource_policy": {
"gpu": {
"enabled": true,
"device_id": 0,
"memory_limit_mb": 1024,
"fallback_to_cpu": true
},
"cpu": {
"max_cores": 2,
"affinity": [4, 5],
"priority": "below_normal",
"thread_pool_size": 4
},
"concurrency": {
"max_concurrent_jobs": 2,
"queue_size": 10,
"job_timeout_ms": 30000
},
"memory": {
"max_image_memory_mb": 512,
"max_model_cache_mb": 1024,
"swap_to_disk": false
},
"scheduling": {
"policy": "round_robin",
"preemption": false,
"watchdog_interval_ms": 1000
}
}
}
}

策略参数

参数类型默认值说明
gpu.enabledBOOLfalse启用 GPU 推理
gpu.device_idDWORD0GPU 设备 ID
gpu.memory_limit_mbDWORD1024GPU 显存上限
gpu.fallback_to_cpuBOOLtrue显存不足时回退 CPU
cpu.max_coresDWORD2最大 CPU 核心数
cpu.affinityDWORD[][]CPU 亲和性绑定
cpu.priorityENUMbelow_normal线程优先级
concurrency.max_concurrent_jobsDWORD2最大并发 Job 数
concurrency.queue_sizeDWORD10排队最大长度
concurrency.job_timeout_msDWORD30000Job 超时时间
memory.max_image_memory_mbDWORD512图像缓存上限
memory.max_model_cache_mbDWORD1024模型缓存上限
scheduling.policyENUMround_robin调度策略
scheduling.watchdog_interval_msDWORD1000看门狗间隔

资源配置建议

场景GPU 显存CPU 核心并发 Job说明
单相机 640×640 检测512 MB11入门配置
双相机 1280×1024 检测2 GB22标准配置
四相机 2448×2048 检测4 GB44高性能配置
边缘设备 (无 GPU)21CPU 推理

结果回写到 PLC

变量映射规范

视觉 Job 执行完成后,结果自动写入 PLC 变量区:

系统变量 (所有视觉 Job 共享):

变量名类型说明
VIS_JOB_BUSYBOOL有 Job 正在执行
VIS_JOB_DONEBOOL最近一次 Job 完成
VIS_JOB_ERRORBOOL最近一次 Job 异常
VIS_JOB_ERROR_IDDWORD错误码
VIS_JOB_IDDWORD当前 Job 序号
VIS_JOB_ELAPSEDREAL执行耗时 (ms)

结果变量 (按 Job 配置):

变量名类型说明
VIS_RESULT_COUNTINT检测目标数
VIS_RESULT_01_CLASSSTRING[32]目标 1 类别
VIS_RESULT_01_CONFREAL目标 1 置信度
VIS_RESULT_01_XREAL目标 1 X
VIS_RESULT_01_YREAL目标 1 Y
VIS_RESULT_01_WREAL目标 1 宽度
VIS_RESULT_01_HREAL目标 1 高度
VIS_RESULT_01_ANGLEREAL目标 1 角度
VIS_RESULT_02_*...目标 2 (最多 256 个)

结果回写流程

1. PLC 设置 VIS_JOB_START = TRUE
2. 运行时检测到上升沿,创建 Job 加入队列
3. Job 开始执行,VIS_JOB_BUSY = TRUE
4. 采集 → 预处理 → 推理 → 后处理
5. 推理完成,结果写入 VIS_RESULT_* 变量
6. VIS_JOB_DONE = TRUE, VIS_JOB_BUSY = FALSE
7. PLC 在下一个扫描周期读到 VIS_JOB_DONE
8. PLC 读取 VIS_RESULT_* 变量
9. PLC 将 VIS_JOB_DONE 清零,准备下一次触发

PLC 侧代码示例 (SCL)

PROGRAM VisionIntegration
VAR
// 触发视觉 Job
trigger_counter : INT := 0;
trigger_pulse : BOOL;
trigger_prev : BOOL;

// 结果接收
has_result : BOOL;
result_count : INT;
i : INT;
END_VAR

// 上升沿检测
trigger_pulse := trigger_signal AND NOT trigger_prev;
trigger_prev := trigger_signal;

// 触发视觉 Job
IF trigger_pulse THEN
VIS_JOB_START := TRUE;
trigger_counter := trigger_counter + 1;
ELSE
VIS_JOB_START := FALSE;
END_IF;

// 读取结果
IF VIS_JOB_DONE AND NOT VIS_JOB_BUSY THEN
// 检查是否出错
IF VIS_JOB_ERROR THEN
// 错误处理
LOG_ERROR("视觉 Job 失败, 错误码: ", VIS_JOB_ERROR_ID);
system_state := STATE_VISION_FAULT;
ELSE
// 读取检测结果
result_count := VIS_RESULT_COUNT;

IF result_count > 0 THEN
// 处理检测结果
FOR i := 1 TO result_count DO
// 根据结果控制逻辑
// ...
END_FOR;

system_state := STATE_PRODUCT_OK;
ELSE
system_state := STATE_PRODUCT_NG;
END_IF;
END_IF;

// 清除完成标志
VIS_JOB_DONE := FALSE;
END_IF;

// 超时保护
IF VIS_JOB_BUSY AND (TIME_SINCE_TRIGGER > T#30S) THEN
VIS_JOB_ABORT := TRUE;
LOG_WARN("视觉 Job 超时, 已中止");
END_IF;
END_PROGRAM

故障处理与超时

故障分类

故障类型错误码可恢复处理方式
相机断开0x1001自动重连,最多 3 次
模型加载失败0x2001回退到上一个版本
推理异常0x3001记录日志,报错到 PLC
显存不足0x4001自动回退到 CPU
内存不足0x4002清理缓存后重试
超时0x5001输出默认值,下次重试
许可限制0x6001提示用户升级许可

故障处理策略

{
"vision": {
"fault_handling": {
"auto_retry": {
"enabled": true,
"max_retries": 3,
"retry_interval_ms": 1000,
"backoff_multiplier": 2.0
},
"camera_reconnect": {
"enabled": true,
"max_attempts": 3,
"interval_ms": 2000
},
"model_fallback": {
"enabled": true,
"fallback_version": "previous"
},
"timeout": {
"default_value_output": true,
"default_count": 0,
"log_timeout": true
},
"fatal": {
"disable_vision": true,
"notify_plc": true,
"notify_operator": true
}
}
}
}

自动恢复流程

检测到故障 ──→ 判断可恢复性
│ │
│ 可恢复 │ 不可恢复
▼ ▼
重试计数 记录日志
│ 通知 PLC
▼ 通知操作员
重试操作 │
│ ▼
├── 成功 → 恢复正常 禁用视觉功能

└── 失败 → 判断是否达到最大重试次数

┌────────┼────────┐
▼ ▼ ▼
相机故障 模型故障 其他故障
重连相机 回退版本 禁用功能

超时处理

超时类型默认值配置位置超时后动作
相机采集超时5000 ms相机配置输出默认值,触发 OnTimeout
模型推理超时30000 msRuntimeResourcePolicy输出默认值,触发 OnTimeout
Job 总超时30000 msRuntimeResourcePolicy中止 Job,触发 OnTimeout
事件处理超时1000 ms事件配置跳过事件,记录日志

性能监控

运行时指标

视觉运行时暴露以下指标,可在 IDE 或 HMI 面板中查看:

指标说明单位
GPU 利用率GPU 计算核心占用率%
GPU 显存使用显存已用量MB
CPU 使用率视觉进程 CPU 占用%
推理延迟平均推理时间ms
采集延迟平均采集时间ms
Job 排队长度当前等待队列长度个数
Job 吞吐量每分钟完成 Job 数个/min
成功/失败率最近 100 次 Job 成功率%

诊断日志

视觉运行时的诊断日志位于 %AppData%/DarraPLC/logs/vision_*.log

[2026-07-20 14:30:00.123] [INFO] [VisionJob] Job #1287 开始执行 (程序: surface_inspect)
[2026-07-20 14:30:00.124] [INFO] [Acquisition] 相机 USB_CAM_1 采集开始, 曝光 5000µs
[2026-07-20 14:30:00.128] [INFO] [Acquisition] 采集完成, 1280×1024, 耗时 4ms
[2026-07-20 14:30:00.129] [INFO] [Preprocessing] 预处理开始 (灰度→高斯滤波→缩放)
[2026-07-20 14:30:00.132] [INFO] [Preprocessing] 预处理完成, 耗时 3ms
[2026-07-20 14:30:00.133] [INFO] [Inference] 推理开始 (模型: surface_defect v3, GPU)
[2026-07-20 14:30:00.141] [INFO] [Inference] 推理完成, 耗时 8ms, 检测到 2 个目标
[2026-07-20 14:30:00.142] [INFO] [Postprocessing] 后处理完成, 耗时 1ms
[2026-07-20 14:30:00.143] [INFO] [ResultWrite] 结果写入 PLC 变量, 2 个目标
[2026-07-20 14:30:00.143] [INFO] [VisionJob] Job #1287 完成, 总耗时 20ms

安全与隔离

进程隔离

视觉运行时在与 PLC 核心不同的进程中运行:

  • PLC 运行时:Windows Service 实时线程,最高优先级
  • 视觉运行时:独立进程,below_normal 优先级
  • 故障隔离:视觉进程崩溃不影响 PLC 运行时

资源隔离

  • CPU 隔离:通过 cpu.affinity 绑定特定核心,不抢占 PLC 核心
  • GPU 隔离:显存上限防止 GPU 显存溢出
  • 内存隔离max_image_memory_mb 防止图像缓存撑爆内存
  • 时间隔离job_timeout_ms 防止视觉任务无限占用