跳到主要内容

虚拟 IO

VirtualDriver 提供纯软件模拟的 IO 驱动,无需任何物理硬件即可运行 PLC 程序。适用于程序开发、逻辑验证和离线调试。

工作原理

VirtualDriver 实现 IHardwareDriver 接口,对 PLC 扫描引擎而言与真实硬件驱动完全等价。切换到虚拟模式只需替换驱动实例,PLC 程序无需修改。

配置

var virtualIO = new VirtualDriver();
virtualIO.Configure(new VirtualIOConfig {
DigitalInputCount = 64, // 64 点 DI
DigitalOutputCount = 64, // 64 点 DO
AnalogInputCount = 16, // 16 通道 AI
AnalogOutputCount = 8 // 8 通道 AO
});

信号操作

手动操作

通过 IO 状态面板直接操作虚拟信号:

操作说明
点击 DI 灯切换 ON/OFF 状态
拖拽 AI 滑块设置模拟量数值
右键 → 强制锁定信号值,不被程序覆盖
右键 → 脉冲产生一个扫描周期的脉冲

脚本驱动

通过 SCL 程序或外部程序批量设置虚拟 IO:

(* 模拟工件到位信号序列 *)
%IX0.0 := TRUE; (* 传感器1触发 *)
WAIT(200); (* 等待200ms *)
%IX0.1 := TRUE; (* 传感器2触发 *)
WAIT(100);
%IX0.0 := FALSE; (* 传感器1复位 *)

仿真联动

虚拟 IO 可与仿真系统的物理模型联动:

  • 夹爪 DO → GripperSimulator → 夹爪 DI 反馈
  • 传送带 AO → ConveyorSimulator → 光电 DI 触发
  • 机床门 DO → 定时器 → 加工完成 DI
与仿真虚拟 IO 的关系

VirtualDriver (HAL 层) 和 VirtualIOSource (仿真层) 功能相似但层级不同。VirtualDriver 是 HAL 硬件抽象层的一个驱动实现,直接参与 IOMerge/IODistribute。VirtualIOSource 是仿真系统的组件,通过 VariableBus 间接提供 IO 数据。在纯仿真模式下两者协同工作。

输出回读

虚拟模式下,DO/AO 输出值可以直接回读为 DI/AI 输入,用于简单的自环测试:

virtualIO.EnableLoopback = true;

// 设置后:
// %QX0.0 的输出值自动映射到 %IX0.0
// %QW0 的输出值自动映射到 %IW0

信号录制

虚拟 IO 支持录制信号变化历史,用于事后分析:

录制内容说明
时间戳精确到扫描周期
信号名称IO 地址 + 变量名
变化值变化前后的值
触发源PLC 程序 / 手动 / 脚本

典型应用

  1. 程序开发 — 无硬件环境下编写和调试 PLC 程序
  2. 逻辑验证 — 验证 IO 联锁逻辑的正确性
  3. 回归测试 — 使用固定信号序列验证程序修改未引入错误
  4. 客户演示 — 展示系统功能而无需携带硬件

仿真场景配置

IDE 提供仿真场景编辑器, 用 YAML 描述信号序列:

scenario: 抽板机完整循环
duration: 30s
signals:
# 0s~1s: 初始化
- at: 0.0
set: "%IX0.0"
value: false
- at: 0.5
set: "%IW100"
value: 25.0 # 温度 25°C

# 1s: 启动按钮按下
- at: 1.0
pulse: "%IX1.0"
duration: 100ms

# 2s~10s: 抽板动作序列
- at: 2.0
wait: "%QX2.0" # 等待气缸伸出信号
timeout: 5s
- at: 2.5
set: "%IX0.1"
value: true # 到位传感器

# 每秒增加温度
- from: 0.0
to: 30.0
step: 1.0
set: "%IW100"
value: "{{ 25 + time * 0.5 }}"

加载场景后点"运行", IDE 自动按时间线驱动虚拟 IO。

随机信号

模拟生产中的随机波动:

- at: 0.0
set: "%IW200"
random:
distribution: normal
mean: 50.0
stddev: 2.0
updateInterval: 100ms

支持分布:

  • uniform (均匀)
  • normal (正态)
  • lognormal (对数正态)
  • custom (自定义曲线)

物理仿真集成

模拟简单物理系统 (如热传导、贮罐液位):

physics:
- type: integrator
input: "%QW100" # 加热功率
output: "%IW101" # 温度
gain: 0.01

- type: firstOrder
input: "%QW200" # 阀门开度
output: "%IW201" # 液位
timeConstant: 10s

- type: delay
input: "%QW300" # 控制输出
output: "%IW301" # 响应
delay: 500ms

适合闭环控制算法 (PID / 预测控制) 的离线调参。

与 VariableBus 集成

Darra 的 VariableBus 是统一仿真数据总线, 连接:

  • VirtualIO (HAL 层)
  • 物理模型 (热/流体/机械)
  • 机器人运动学
  • HMI 显示

三者通过 VariableBus 共享数据, 仿真时自然联动。详见仿真架构文档。

录制与回放

运行真实系统时录制信号, 离线回放用于问题重现:

recorder.Start(signals: new[] { "%IX0.*", "%QW*" });
// ... 让系统运行一段
recorder.Stop();
recorder.SaveAs("bug_repro.sim");

// 在开发机上
virtualIO.LoadRecording("bug_repro.sim");
virtualIO.Replay(speed: 0.5); // 慢放 0.5 倍

支持:

  • 全速 / 慢放 / 快进
  • 断点 (到某时刻暂停, 手工检查)
  • 逐周期步进

混合仿真

真实硬件 + 虚拟 IO 混合:

  • 真实 EtherCAT 伺服轴 (真电机真编码器)
  • 虚拟的限位传感器和操作面板
  • 真实 HMI 触摸屏

场景: 机器人本体是真实的, 周边的产线状态用虚拟代替, 用于独立验证机器人程序。

性能

VirtualDriver 的 Read/Write 是内存操作, 耗时 < 1μs, 不影响 PLC 周期。单机可同时驱动 10,000+ 虚拟点位无压力。

切换策略

项目配置决定用虚拟还是真实 IO:

项目设置 → 部署目标:
[ ] 真实硬件 (生产)
[x] 虚拟 (仿真)
[ ] 混合 (见混合仿真)

切换时 PLC 代码完全不改, 只改部署目标后重新下载。

排错

症状处理
仿真运行但 IO 值不变检查场景脚本的信号地址
物理模型发散增益或时间常数不合理, 减小步长
录制回放比原时序慢回放引擎被重型场景拖累, 降速或简化
强制信号和场景冲突强制值优先, 场景被忽略
随机信号不重现设随机种子 random.seed: 12345