
写在前面为什么用 realvirtual 练虚拟调试虚拟调试在工业自动化圈子里已经不是一个新概念但真正把它用到项目里的团队仍然会卡在“平台怎么选”和“协议怎么通”这两件事上。这次我们以倍福 Beckhoff 的 TwinCAT 为例把 realvirtual 的虚拟调试流程完整走一遍从环境准备、PLC 通信建立到 Unity 场景中的信号联动再到用 ADS 接口做自动化测试。整个过程不需要接任何真实硬件最适合做产线方案验证、PLC 程序调试和技术培训。realvirtual 是运行在 Unity 引擎上的数字孪生 / 虚拟调试平台它的核心能力是把 PLC 程序与虚拟 3D 场景连接起来。而 TwinCAT 是倍福的自动化软件平台包含实时操作系统、PLC 编程环境和 EtherCAT 主站功能。在真实项目中TwinCAT 可以直接控制伺服驱动器、I/O 模块和各种传感器在虚拟调试中我们把“设备”换成 Unity 里的 3D 模型通过 ADS 通信协议让 PLC 程序以为自己在控制一台真实机器。1. 核心能力速览能力项说明项目类型Unity 数字孪生 / 虚拟调试平台支持多 PLC 协议对接主要关联软件Beckhoff TwinCAT 3、Unity、realvirtual 插件通信协议ADSTwinCAT 原生协议也可扩展 Modbus、OPC UA 等硬件依赖需要 x86/X64 Windows 主机无额外运动控制硬件要求场景用途PLC 程序验证、产线虚拟调试、逻辑训练、方案演示启动方式Unity Editor 内运行TwinCAT 作为独立运行时后台运行是否支持 API支持可通过 ADS 接口如 pyads读写 PLC 变量是否支持批量任务可以结合自动化测试脚本做批量回归验证上手门槛需要掌握 Unity 基础操作 TwinCAT 基本配置适合读者自动化工程师、数字孪生开发者、PLC 调试人员从表格能看出来这套方案的核心不是“把 3D 场景做得好看”而是建立一条“PLC 变量 ↔ 场景对象状态”之间的双向链路。传感器、气缸、电机、输送带都可以映射为 PLC 输入输出信号或内部变量。2. 适用场景与使用边界2.1 推荐场景PLC 程序开发验证在没有真实设备的情况下把 TwinCAT 里的逻辑先跑通。比如写了一套气缸顺序控制程序不确定时序是否冲突直接放到虚拟场景里运行能直观看到每个气缸的伸出缩回顺序。产线方案演示把机械方案、电气方案和程序逻辑整合进一个 3D 场景中给客户或领导展示。视觉效果好交互性强比 PPT 讲方案更有说服力。操作员培训建立虚拟产线环境让新员工在安全状态下熟悉操作流程。培训过程不会损坏设备也不存在停机风险。自动化回归测试配合脚本批量运行测试用例验证 PLC 程序修改后没有引入新问题。这是从“演示”走向“工程化验证”的关键步骤。2.2 不推荐场景与边界提醒高实时性运动控制如果涉及极端高精度的多轴插补或 ms 级硬实时任务虚拟环境不能替代真实硬件测试。ADS 通信和 Unity 的物理引擎都引入了额外的延迟不适合验证伺服同步精度。物理准确性要求极高的场景例如碰撞变形分析、流体仿真需要专门的多体动力学或有限元工具realvirtual 的物理引擎更偏逻辑级验证。商业交付时的授权问题realvirtual 需要 Unity 授权TwinCAT 需要倍福的授权机制项目中的 CAD 模型和素材也要确认版权来源。不要在客户交付现场使用未授权软件。安全意识虚拟调试只能覆盖逻辑层面的验证不能覆盖接线错误、信号干扰、接地问题等物理层故障。最终现场联调仍然不可省略虚拟调试的价值是把程序层面的问题提前消除。3. 开发环境与前置条件3.1 操作系统TwinCAT 3 目前主要运行在 Windows 10 / Windows 11 专业版或企业版建议使用 x86 / x64 架构。不建议在 LTSC 或精简版系统上安装容易缺少组件。Unity 同样支持 Windows 平台两者可以装在同一台机器上。开发调试阶段建议一台主机同时运行 TwinCAT 实时系统和 Unity 编辑器这样省去网络路由配置的麻烦。3.2 软件清单软件作用备注Windows 10/11宿主平台建议专业版以上以保证实时网卡和系统服务正常Unity3D 场景运行引擎建议 2021 LTS 或更高版本需包含 Windows Build SupportrealvirtualUnity 插件从 Unity Asset Store 获取授权导入后提供 PLC 连接组件TwinCAT 3 XAEPLC 编程与运行时需要合法授权Trial 模式可在测试环境使用时间限制以倍福授权策略为准Visual Studio / TwinCAT ShellPLC 编辑环境如果使用独立 Shell可以不装完整 VS3.3 硬件建议CPUTwinCAT 需要运行实时任务Unity 需要场景渲染建议 4 核以上性能越高越好。内存16 GB 起步复杂 3D 场景建议 32 GB。虚拟调试时Unity 编辑器、TwinCAT 运行时和浏览器调试工具会同时占用内存。显卡Unity 场景需要 GPU 加速建议使用独立显卡。集显在小场景下也能运行但帧率不稳定影响体验。网络如果 TwinCAT 和 Unity 在同一台机器上使用本地路由即可如果分机运行需要保证以太网互通并正确配置 AMS NetId 路由。这些要求都是通用基线。实际占用取决于场景资源质量和 PLC 任务复杂度建议先从小场景验证不要一开始就导入整条产线的高精度 CAD 模型。4. TwinCAT 环境准备与 ADS 通信基础4.1 TwinCAT 安装与启动安装 TwinCAT 3 时通常需要先安装 Visual Studio 组件或直接使用倍福提供的独立 TwinCAT XAE Shell。安装完成后打开 TwinCAT 开发环境在工具栏中会看到“Activate Configuration”和“Restart TwinCAT”按钮。首次使用需要激活运行时授权测试环境可以使用评估模式但要注意倍福的授权时间限制。启动 TwinCAT 后系统会在 Windows 服务中创建实时任务并生成一个 AMS NetId。这个 NetId 是 ADS 通信的寻址基础后面的 realvirtual 连接、pyads 脚本调用都依赖它。4.2 AMS NetId 与 ADS 端口说明在 ADS 通信中每个设备有一个 6 段的 AMS NetId例如192.168.0.1.1.1前 4 段通常对应 IP 地址或自定义编号。后 2 段表示设备或路由标识。PLC 运行时默认监听端口通常为 851这是 TwinCAT 3 PLC Runtime 的常见默认 ADS 端口具体要以实际配置为准。在 realvirtual 中连接 TwinCAT 时需要提供目标 AMS NetId 和端口号。如果连接不上最先检查的永远是这两个值。4.3 创建最简 PLC 项目打开 TwinCAT 开发环境新建一个 PLC 项目选择标准 IEC 61131-3 语言。在MAIN程序中输入下面这段最简单的逻辑PROGRAM MAIN VAR bSensorAtPos : BOOL; // 来自虚拟传感器的输入 bCylinderOut : BOOL; // 控制虚拟气缸的输出 tonCylinder : TON; // 定时器防止气缸动作过快 END_VAR tonCylinder(IN : bSensorAtPos, PT : T#500MS); IF tonCylinder.Q THEN bCylinderOut : TRUE; ELSE bCylinderOut : FALSE; END_IF这段逻辑把传感器信号与气缸输出关联起来传感器为TRUE后 500ms气缸伸出传感器消失后定时器复位气缸缩回。编译通过后先不急着激活等 realvirtual 场景准备好再统一启动。4.4 检查本地 ADS 路由与防火墙在 TwinCAT 中进入路由配置确认目标设备的 NetId 是否已经添加到路由列表。如果 Unity 和 TwinCAT 在同一台机器上通常可以直接使用本机 NetId不需要额外添加远程路由。还需要在 Windows 防火墙中放行 TwinCAT 相关的 UDP/TCP 端口否则 ADS 请求会被系统拦截。可以先临时关闭防火墙测试连通性确认是防火墙问题后再添加精确的放行规则不要长期关闭防火墙。5. 在 realvirtual 中创建虚拟调试项目5.1 导入 realvirtual 插件从 Unity Asset Store 获取 realvirtual 插件后在 Unity 中打开 Package Manager 完成导入。导入完成后菜单栏会出现 realvirtual 相关入口。如果还没有现成的 3D 产线模型建议直接使用 realvirtual 自带的示例场景里面包含传送带、传感器、气缸、工件等常见对象是验证 PLC 通信链路的最快方式。5.2 添加 PLC 控制器并配置 ADS在 realvirtual 的层级面板中创建或找到 PLC 对象。在控制器的配置界面选择通信协议为 ADS然后填写关键参数配置项示例值说明AMS NetId192.168.0.1.1.1TwinCAT 目标机器的 NetId需要与 4.2 节一致ADS Port851PLC Runtime 的 ADS 端口默认值以实际配置为准轮询周期50 msADS 通信频率越小实时性越高但 CPU 开销也越大不同版本的 realvirtual 界面字段名称可能略有差异但核心参数是一样的。如果连接失败优先检查 NetId 和端口号再看防火墙。5.3 建立信号映射PLC 与 3D 对象之间通过信号绑定实现联动。例如场景中有一个气缸对象它有一个“伸出/缩回”状态。PLC 程序里有一个输出变量GVL.bCylinderOut。在 realvirtual 中把气缸的伸出动作绑定到该变量。当 PLC 置位该变量时气缸在 Unity 场景中伸出PLC 复位该变量时气缸缩回。同时在场景中放置一个虚拟传感器。当工件到达触发位置时传感器输出TRUE该值写入 PLC 的输入变量GVL.bSensorAtPos。这样PLC 的逻辑“如果传感器有信号则伸出气缸”就能在虚拟环境中完整运行。信号映射关系可以用一张表维护realvirtual 对象场景行为PLC 变量方向Sensor_Pos1工件触发GVL.bSensorAtPos场景到 PLCCylinder1伸出/缩回GVL.bCylinderOutPLC 到场景信号映射表是整个虚拟调试项目的“接口文档”。维护好这张表后期排查问题会省很多时间。6. 虚拟调试基础功能测试6.1 测试场景气缸 传感器先建立最简测试场景不要直接上整条产线。一个气缸、一个传感器、一个 PLC 程序就足够验证链路。这里使用前面已经写好的 TwinCAT 程序逻辑很简单传感器触发 500ms 后气缸伸出传感器消失后气缸缩回。6.2 启动 TwinCAT 运行时回到 TwinCAT 开发环境点击“Activate Configuration”把 PLC 程序下载到本地运行时然后切换到 Run 模式。此时 PLC 程序已经在后台运行不需要连接任何硬件 I/O。可以通过 TwinCAT 的 Online 视图观察变量变化确认系统状态正常。6.3 在 Unity 中运行 realvirtual 场景回到 Unity点击 Play 进入运行模式。realvirtual 会自动连接 PLC。此时预期顺序是Unity 场景中气缸处于缩回状态。把一个虚拟工件拖到传感器触发区域传感器的值变为TRUE。等待约 500ms 后气缸在场景中伸出。把工件移开传感器复位气缸缩回。如果这些动作都按预期发生说明双向通信已经建立PLC 输出控制场景物体场景传感器反馈到 PLC 输入。6.4 判断测试是否成功变量值能在 realvirtual 的调试面板中正确显示。场景对象的动作与 PLC 内部变量的状态保持同步。修改 PLC 程序逻辑后Unity 中的行为能对应变化。这一步是整个虚拟调试项目的基础。如果最小链路不通后面的复杂场景都不会通。先保证最小链路稳定再扩展功能。7. 使用 pyads 做接口调用与自动化测试7.1 为什么需要 pyadsrealvirtual 的场景运行依赖 Unity但某些自动化验证场景中我们可能不希望每次都在 Unity 编辑器里手动操作。此时可以使用 ADS 的 Python 库pyads直接从外部脚本读写 PLC 变量。pyads 的价值在三个场景中最明显连接状态检查、批量写入测试信号、收集 PLC 内部变量做日志分析。虚拟调试从“手动演示”升级到“自动化回归测试”时pyads 是核心工具。7.2 安装 pyadspip install pyads7.3 连接 TwinCAT 并读写变量import pyads # 替换为你的 TwinCAT 设备 AMS NetId 和端口 PLC_AMS_NET_ID 192.168.0.1.1.1 PLC_PORT 851 plc pyads.Connection(PLC_AMS_NET_ID, PLC_PORT) plc.open() # 读取一个 BOOL 变量 val plc.read_by_name(GVL.bSensorAtPos, pyads.PLCTYPE_BOOL) print(bSensorAtPos , val) # 写入一个 BOOL 变量 plc.write_by_name(GVL.bForceOutput, True, pyads.PLCTYPE_BOOL) plc.close()这段代码展示了最常用的 ADS 读写方式。实际项目中的变量名要与 TwinCAT 工程中的完整路径一致包括库前缀、全局变量列表名和变量名。7.4 批量自动化测试脚本下面给一个完整的批量回归测试脚本把测试用例、执行、结果输出整合在一起import csv import time import pyads PLC_AMS_NET_ID 192.168.0.1.1.1 PLC_PORT 851 plc pyads.Connection(PLC_AMS_NET_ID, PLC_PORT) plc.open() # 测试用例表(输入信号, 输入值, 等待秒数, 预期输出信号, 预期值) test_cases [ (GVL.bTestStart, True, 1.0, GVL.bTestDone, True), (GVL.bTestReset, True, 1.0, GVL.bTestDone, False), ] results [] for input_name, input_val, wait, expected_name, expected_val in test_cases: plc.write_by_name(input_name, input_val, pyads.PLCTYPE_BOOL) time.sleep(wait) actual plc.read_by_name(expected_name, pyads.PLCTYPE_BOOL) passed (actual expected_val) results.append([input_name, expected_name, expected_val, actual, passed]) print(f{expected_name} {actual}, expected {expected_val}, {PASS if passed else FAIL}) # 复位输入信号避免影响下一条用例 plc.write_by_name(input_name, not input_val, pyads.PLCTYPE_BOOL) with open(test_results.csv, w, newline) as f: writer csv.writer(f) writer.writerow([input, output, expected, actual, passed]) writer.writerows(results) plc.close()这段脚本把测试结果写入 CSV 文件方便集成到 CI/CD 或自动化测试平台中。实际使用时要根据项目中的变量类型调整PLCTYPE_BOOL为对应的类型。8. 性能观察与资源占用8.1 重点观察的指标虚拟调试运行时重点看三个指标Unity 场景帧率帧率低场景操作不流畅影响交互调试。TwinCAT 循环周期是否稳定如果 PLC 任务周期抖动明显说明实时环境配置有问题。ADS 通信延迟延迟高传感器信号反馈到 PLC 的响应变慢。如果 Unity 帧率很低场景不跟手通常不是 PLC 通信问题而是 3D 资源过重比如材质、粒子、动态光源消耗了太多 GPU 资源。优先检查 Draw Call 数量和阴影质量。8.2 实时性边界TwinCAT 的 PLC 任务本身是硬实时的但 realvirtual 与 TwinCAT 之间的 ADS 通信不是硬实时链路。因此虚拟调试的物理反应速度不能完全等于真实设备。合理的使用方式是把虚拟调试当成“逻辑验证工具”而不是“硬件实时性测试工具”。如果需要在虚拟环境中验证伺服精度或总线周期抖动需要用专门的实时仿真方案本文方案覆盖不了这部分。8.3 降低负载的方法使用简化模型替代高精度 CAD 模型尤其是圆柱面、螺纹等细节丰富的零件。减少场景中的实时反射、阴影和抗锯齿开销。将 ADS 轮询周期从 10ms 调整为 50ms 或 100ms降低通信频率。将不参与逻辑联动的装饰对象从场景中移除。批量测试时关闭 Unity 的实时渲染画面只用后台模式运行。9. 常见问题与排查方法问题现象可能原因排查方式解决方案realvirtual 无法连接 TwinCATAMS NetId 配置错误在 TwinCAT 路由配置中确认 NetId修改为正确的 AMS NetIdADS 连接一直超时防火墙阻止 ADS 端口检查防火墙日志临时关闭防火墙测试放行 TwinCAT 所需的 UDP/TCP 端口Unity Play 后变量无变化PLC 未进入 Run 模式查看 TwinCAT 中 PLC 的运行状态激活配置并启动 PLC信号绑定后动作方向反了变量极性配置错误观察变量值与场景动作方向反转绑定信号的取反选项场景卡顿严重3D 资源过重或物理计算量大查看 Unity Profiler 和帧率优化模型、降低渲染质量修改 PLC 程序后不生效未重新激活配置在 TwinCAT 中重新编译并下载二次激活配置并重启 PLCpyads 读取变量失败变量路径错误或类型不匹配打印异常信息检查变量名对照 TwinCAT 工程中的完整路径修改批量测试中某个用例卡住信号未复位导致逻辑死锁添加超时机制在脚本中增加 wait 超时或强制复位10. 最佳实践与使用建议10.1 先跑最小链路刚接触这套平台时不要直接把整条产线搬进 Unity。先建立一个“传感器 气缸 定时器逻辑”的最小场景验证通信链路稳定后再逐步加入输送带、机器人和多工位。这个思路不仅能降低调试难度还能让你在早期暴露问题时不至于大海捞针。10.2 变量命名要有规范虚拟调试项目里的变量会直接暴露给 Unity 场景命名不规范会导致后期维护困难。建议统一使用可读性强的命名格式GVL_Btn_Start GVL_Sensor_Pos1 GVL_Cylinder_Out1这样在 realvirtual 中绑定信号时一眼就能看出变量的类型和用途。PLC 程序、Unity 场景、测试脚本里的变量名保持一一对应能避免很多低级错误。10.3 做好版本管理TwinCAT 工程、Unity 工程、模型素材、Python 测试脚本要分开做版本管理。每次修改 PLC 逻辑后重新跑一遍自动化回归用例避免新逻辑破坏已有功能。建议在 git 中同时维护一份信号映射表作为接口文档。10.4 注意授权与版权TwinCAT、Unity、realvirtual 都是商业软件要确认好授权范围。不要使用未经许可的 CAD 模型或产品素材作为展示内容。如果虚拟调试涉及客户产线方案需要与合作伙伴确认保密义务。10.5 虚拟调试不能完全替代现场联调虚拟调试覆盖面广但无法模拟接线错误、信号干扰、机械磨损和通讯抖动。完成虚拟调试后仍然需要按现场安全规范进行真机调试把虚拟调试结果作为测试依据之一而不是唯一依据。这也是自动化工程项目的常规做法。11. 总结与下一步realvirtual TwinCAT 这套组合最适合的场景是“在没有硬件的情况下把 PLC 程序逻辑先在 Unity 里跑起来”。它解决的核心问题是逻辑验证效率不需要等待机械到位不需要担心接线先把程序错误暴露在虚拟环境里。看完这篇文章建议你按这个顺序验证先把 TwinCAT 装好、确认本地 ADS 通信通再导入 realvirtual 示例场景跑通一个最小信号链路然后用 pyads 做一两个自动化读写脚本。最小链路跑通之后再往里面加输送带、机器人、多工位虚拟调试的价值才会真正放大。如果你想继续深入下一步可以学习如何接入 OPC UA、如何处理多台 PLC 协同逻辑、如何把真实 HMI 画面与虚拟场景联动。也可以研究如何把虚拟调试应用到 AGV 调度、仓储分拣等更复杂的场景中。这套思路熟练之后你会发现自己调试产线程序的时间明显缩短方案展示也更有说服力。