AOI 光学检测工站
1. 设备简介
AOI (Automated Optical Inspection, 自动光学检测) 是 3C 电子、PCB、精密五金、 新能源电池极片等制造场景的核心质量工位。以相机 + 光源 + 算法组合, 对产品外观缺陷 (划伤、脏污、缺料、偏移、字符错漏) 进行逐件 100% 检测。
本案例为某珠三角 PCBA 工厂贴片后 AOI 工位, 由 Darra 平台统一承接 AOI 的
运动控制 / 视觉触发 / 节拍调度, 视觉算法由厂内工程师自行用 Python +
OpenCV / Halcon 迭代。Darra 不内置任何视觉算法, 而是提供 Python 3.11
协程宿主, 让算法团队自由 import cv2 / import halcon / import torch,
并在保存 .py 时热更新, 无需重启 PLC。
主要工位流程:
- 上游贴片机来板 → 输送带到位
- X/Y/θ 三轴伺服对位夹紧
- 光源亮 + 上下相机硬触发 (EtherCAT DC 0.5ms 同步)
- Python 协程异步推理 (OpenCV 快检 + ONNX 深度模型二检)
- OK/NG 分拣 → MES 追溯 (BoardID + 缺陷坐标 + 图像留档)
关键能力: 单板节拍 ≤ 3.5 s, 硬触发延迟 ≤ 0.5 ms, 检出率 ≥ 99.5%, 误报率 ≤ 0.3%, 算法团队可脱离机电工程师独立发版。
2. 项目模块组成
本工站是 机械 + 电气 + 软件 三层协同项目, 全部由 Darra IDE 统一管理。
| 层次 | 模块 | 职责 |
|---|---|---|
| 机械 | XY/Z/θ 对位平台 | 将来板精准定位到相机视场中心 |
| 机械 | 相机支架 + 光源 | 上下双面打光 + 图像采集 |
| 机械 | NG 分拣机构 | 气缸推出 NG 板至废品道 |
| 电气 | EtherCAT 主干 | 1ms 周期, 驱动伺服 + IO + 光源 |
| 电气 | GigE/USB3 图像总线 | 独立与控制总线, 避免视觉流量占用 EtherCAT |
| 电气 | Cat 3 安全回路 | 光幕 + 急停 + 双触点继电器 |
| 软件 | PLC 主程序 | 状态机调度 (7 状态), SCL 语言 |
| 软件 | 运动工艺对象 | MC_MoveAbs + 三轴联动, 内置 |
| 软件 | Python 脚本宿主 | 异步协程, 保存即热更新 |
| 软件 | HMI 组态 | 8 页 (主界面 / 缺陷热图 / 报警 / 配方 / MES / 统计 / 维护 / 设置) |
| 软件 | MES 网关 | 每板上传 50+ 字段 |
3. 机械装配架构
装配要点:
- XY 滚珠丝杠精度 ±3 μm, θ 轴采用直驱电机 (免减速器回差)
- Z 轴采用 400W 带抱闸伺服, 保证断电不坠落
- 顶部相机固定在 Z 轴下方, 随 Z 下降到工作高度
- 底部相机反向安装, 与背光板形成 "透射模式"
- 安全光幕 20 光轴 14mm 栅距, 双侧防护
4. 程序架构
4.1 OB/FB 调用树
4.2 状态机流转
任务调度:
- OB1 (1ms): 主逻辑、状态机、运动指令发送
- OB35 (250us): 安全监控 + 高速光电 IO 刷新
- OB100: 上电初始化 + 伺服使能 + 回零
5. 硬件 BOM
单位: 人民币 (含税)。2026 年 3 月珠三角参考价, 批量可再议 10~15%。
| 序号 | 分类 | 品牌 / 型号 | 规格 | 数量 | 单价 (¥) | 小计 (¥) |
|---|---|---|---|---|---|---|
| 1 | 工控机 | 研华 IPC-610MB | i7-12700 / 32G / 1T SSD + RTX A2000 6G | 1 | 18,500 | 18,500 |
| 2 | 触摸屏 | 昆仑通态 MCGS 21.5" | 1920×1080 电容多点 | 1 | 4,200 | 4,200 |
| 3 | 伺服驱动 | 汇川 SV660N | EtherCAT 400W | 4 | 1,680 | 6,720 |
| 4 | 伺服电机 | 汇川 ISMH 系列 | 400W 2500ppr 带抱闸 | 4 | 1,320 | 5,280 |
| 5 | 远程 IO | 汇川 AM600-CPU1608TP + 扩展 | 32DI + 32DO + 8AI + 4AO | 1 | 3,850 | 3,850 |
| 6 | 工业相机 (上) | 海康 MV-CS050-10GC | 500 万彩色 GigE | 1 | 4,800 | 4,800 |
| 7 | 工业相机 (下) | 海康 MV-CU050-90UM | 500 万黑白 USB3.0 | 1 | 3,600 | 3,600 |
| 8 | 工业镜头 | 海康 MVL-KF2528M-12MP | 25mm F2.8 定焦 500万级 | 2 | 1,200 | 2,400 |
| 9 | 环形光源 | 奥普特 OPT-RI15050-W | 环形白光 150mm | 1 | 2,800 | 2,800 |
| 10 | 背光光源 | 奥普特 OPT-DBL100-B | 背光板蓝 100×100 | 1 | 2,400 | 2,400 |
| 11 | 光源控制器 | 奥普特 OPT-APD4024F-4-V | 4 通道数字可调, EtherCAT | 1 | 1,900 | 1,900 |
| 12 | 对位平台 | 自制滚珠丝杠组件 | XY 100×100 / Z 30 / θ ±5° | 1 | 8,500 | 8,500 |
| 13 | 安全光幕 | 嘉准 JH-LG-1200 | 20 光轴 14mm | 2 | 1,450 | 2,900 |
| 14 | 光电传感器 | 邦纳 BGS 漫反射 | PNP / 15 mm | 8 | 320 | 2,560 |
| 15 | NG 分拣气缸 | SMC MXH20-60Z | 双行程 60mm | 2 | 480 | 960 |
| 16 | 电磁阀岛 | 亚德客 4V210-08 × 8 | EtherCAT 从站 | 1 | 1,980 | 1,980 |
| 17 | 工业交换机 | 华三 S1224F-HPWR | 24 口工业网管 | 1 | 1,800 | 1,800 |
| 18 | UPS | 山特 C3K | 3 kVA 长效 | 1 | 3,200 | 3,200 |
| 19 | 线缆 / 配件 | 汇川 Cat5e / 动力线 / 气管 | - | 1 | 4,600 | 4,600 |
| 20 | 机柜 + 机架 | 威图 TS8 + 铝型材 | 800×600×2000 + 工作台 | 1 | 12,000 | 12,000 |
| 电气小计 | ¥94,950 | |||||
| 机械结构件 | ¥53,050 | |||||
| 合计 | ¥148,000 |
6. IO 模块配置 (IDE 操作流程)
6.1 选择 IO 模块
在 Darra IDE 里依次操作:
- 工程 → IO 设备向导 → 选择 "EtherCAT 主站"
- 扫描从站 (Alt+F5), 自动发现:
- 汇川 AM600-CPU1608TP (节点 1)
- 汇川 SV660N ×4 (节点 2~5, X/Y/Z/θ)
- 奥普特 OPT-APD4024F-4-V (节点 6)
- 亚德客阀岛 8 路 (节点 7)
- 逐个从站 → 设置别名 (Alias) 便于后期维护
6.2 IO 地址分配表
| 模块 | 通道 | 地址 | 方向 | 类型 | 别名 |
|---|---|---|---|---|---|
| AM600 DI | Ch0 | I0.0 | DI | BOOL | SEN_BoardIn |
| AM600 DI | Ch1 | I0.1 | DI | BOOL | SEN_BoardReady |
| AM600 DI | Ch2 | I0.2 | DI | BOOL | SEN_CamTop_Ready |
| AM600 DI | Ch3 | I0.3 | DI | BOOL | SEN_CamBot_Ready |
| AM600 DI | Ch4 | I0.4 | DI | BOOL | SEN_NGBin_Full |
| AM600 DI | Ch5 | I0.5 | DI | BOOL | SEN_EStop |
| AM600 DI | Ch6 | I0.6 | DI | BOOL | SEN_LightCurtain_OK |
| AM600 DO | Ch0 | Q0.0 | DO | BOOL | ACT_Clamp |
| AM600 DO | Ch1 | Q0.1 | DO | BOOL | ACT_CamTrig_Top |
| AM600 DO | Ch2 | Q0.2 | DO | BOOL | ACT_CamTrig_Bot |
| AM600 DO | Ch3 | Q0.3 | DO | BOOL | ACT_NG_Cyl |
| AM600 DO | Ch4 | Q0.4 | DO | BOOL | ACT_Tower_Green |
| AM600 DO | Ch5 | Q0.5 | DO | BOOL | ACT_Tower_Red |
| AM600 AO | Ch0 | AQ0 | AO | INT | LED_Top_Intensity |
| AM600 AO | Ch1 | AQ1 | AO | INT | LED_Bot_Intensity |
| APD4024 | Ch0~3 | - | 通过 CoE 写 | LED_Channel1~4 | |
| SV660N_X | PDO | - | 运动轴 | AXIS_REF | AxisX |
| SV660N_Y | PDO | - | 运动轴 | AXIS_REF | AxisY |
| SV660N_Z | PDO | - | 运动轴 | AXIS_REF | AxisZ |
| SV660N_θ | PDO | - | 运动轴 | AXIS_REF | AxisTheta |
6.3 IO 用途分工
| 组别 | 用途 | 参与设备 |
|---|---|---|
| 物料感知 | 来板到位、夹紧状态、分拣状态 | SEN_BoardIn / BoardReady / NGBin_Full |
| 视觉握手 | 相机硬触发 + 就绪反馈 | ACT_CamTrig_Top/Bot, SEN_CamTop/Bot_Ready |
| 光源调光 | 顶部 / 底部亮度 | LED_Top/Bot_Intensity (AO) + APD4024 (CoE) |
| 执行机构 | 夹紧、分拣气缸、报警灯 | ACT_Clamp, ACT_NG_Cyl, ACT_Tower_* |
| 安全回路 | 光幕 + 急停硬接 Cat 3 继电器 | SEN_EStop, SEN_LightCurtain_OK |
| 运动控制 | X/Y/Z/θ 四轴 | AxisX/Y/Z/θ via EtherCAT PDO |
6.4 数据绑定到机器人
本工站不使用独立机器人, 而是由 Darra 内置 3D 插补工艺对象驱动 XY/Z/θ 四轴构成虚拟 4 自由度机器人, 对位操作直接在 PLC 工程里调用:
(* 将 IO 采集的板位置传递给 "虚拟机器人" *)
Robot.TargetPose.X := Recipe.PickX;
Robot.TargetPose.Y := Recipe.PickY;
Robot.TargetPose.Z := Recipe.PickZ;
Robot.TargetPose.C := 0.0; (* θ 归零 *)
Robot.MoveL(Vel := 400, Acc := 2000);
绑定规则 (在 IDE 的 "机器人配置" 对话框里设置):
| 机器人通道 | Darra 轴 | 物理对应 |
|---|---|---|
| J1 (X) | SV660N 节点 2 | 对位 X 丝杠 |
| J2 (Y) | SV660N 节点 3 | 对位 Y 丝杠 |
| J3 (Z) | SV660N 节点 4 | Z 升降 |
| J4 (C) | SV660N 节点 5 | θ 旋转台 |
运动指令由 FB_Motion 统一封装, 失败时自动回退到原点。
7. 核心数据结构 UDT + DB
// 板数据 UDT
TYPE UDT_AOI_Board :
STRUCT
BoardID : STRING[32]; // 板序号 (MES 下发)
Recipe : STRING[16]; // 产品型号
ArriveTime : DT; // 到站时间戳
PosX_mm : LREAL; // 实际 X 位置
PosY_mm : LREAL; // 实际 Y 位置
Theta_deg : LREAL; // 角度偏差
ImageTopPath : STRING[128]; // 顶部图像路径
ImageBotPath : STRING[128]; // 底部图像路径
InspectState : USINT; // 0=未检 1=检测中 2=OK 3=NG
DefectCount : UDINT; // 缺陷总数
CycleTime_ms : UDINT; // 节拍耗时
END_STRUCT
END_TYPE
// 缺陷结果 UDT (单个)
TYPE UDT_DefectResult :
STRUCT
DefectType : USINT; // 1=短路 2=断路 3=缺件 4=偏移 5=极性 6=字符
LocationX_px : UINT; // 缺陷像素 X
LocationY_px : UINT; // 缺陷像素 Y
WorldX_mm : LREAL; // 世界坐标 X (mm)
WorldY_mm : LREAL; // 世界坐标 Y (mm)
Confidence : REAL; // AI 置信度 0.0~1.0
Severity : USINT; // 0=轻微 1=一般 2=严重
ImageCrop : STRING[128]; // 局部图路径 (切片)
END_STRUCT
END_TYPE
// 配方 UDT
TYPE UDT_Recipe :
STRUCT
RecipeName : STRING[32];
PickX, PickY, PickZ : LREAL; // 对位目标
LEDTop_Pct : USINT; // 顶部光源亮度
LEDBot_Pct : USINT; // 底部光源亮度
ExposureMs : UINT; // 曝光时间
ModelPath : STRING[128]; // AI 模型路径
UseAI : BOOL; // 是否启用深度模型
END_STRUCT
END_TYPE
// 全局 DB
VAR_GLOBAL
CurBoard : UDT_AOI_Board;
Defects : ARRAY[1..64] OF UDT_DefectResult;
CurRecipe : UDT_Recipe;
TotalPass : UDINT;
TotalFail : UDINT;
END_VAR
8. 核心程序代码
8.1 主状态机 (7 状态)
PROGRAM PRG_AOI_Main
VAR
State : INT := 0;
TON_Timeout : TON;
Py_Result : INT; // 0=Pending 1=OK 2=NG
CycleStart, CycleEnd : DT;
END_VAR
CASE State OF
0: (* Idle: 等板到位 *)
IF SEN_BoardIn THEN
CycleStart := DT#NOW;
CurBoard.BoardID := MES.ReadBoardID();
CurBoard.Recipe := MES.ReadRecipe(CurBoard.BoardID);
CurBoard.ArriveTime := CycleStart;
ACT_Clamp := TRUE;
State := 1;
END_IF
1: (* Loading: 夹紧 + 对位轴联动 *)
Robot.TargetPose.X := CurRecipe.PickX;
Robot.TargetPose.Y := CurRecipe.PickY;
Robot.TargetPose.Z := CurRecipe.PickZ;
Robot.TargetPose.C := 0.0;
Robot.MoveL(Vel := 400, Acc := 2000);
IF Robot.Done THEN
State := 2;
END_IF
2: (* Positioning: 光源亮, 硬触发相机 *)
LED_Top_Intensity := CurRecipe.LEDTop_Pct;
LED_Bot_Intensity := CurRecipe.LEDBot_Pct;
ACT_CamTrig_Top := TRUE;
ACT_CamTrig_Bot := TRUE;
TON_Timeout(IN := TRUE, PT := T#100ms);
IF TON_Timeout.Q THEN
ACT_CamTrig_Top := FALSE;
ACT_CamTrig_Bot := FALSE;
TON_Timeout(IN := FALSE);
State := 3;
END_IF
3: (* Imaging: 等相机回传 → 调 Python 异步脚本 *)
IF SEN_CamTop_Ready AND SEN_CamBot_Ready THEN
Py_Result := 0;
PyScript.InvokeAsync(
Script := 'aoi_inspect.py',
Method := 'run',
Arg1 := ADR(CurBoard),
Arg2 := ADR(Py_Result)
);
State := 4;
END_IF
4: (* Inspecting: 等 Python 回调 *)
IF Py_Result <> 0 THEN
IF Py_Result = 1 THEN
CurBoard.InspectState := 2; (* OK *)
TotalPass := TotalPass + 1;
ELSE
CurBoard.InspectState := 3; (* NG *)
TotalFail := TotalFail + 1;
END_IF
State := 5;
ELSIF TON_Timeout.ET > T#3s THEN
CurBoard.InspectState := 3;
Alarm(Code := 1001, Msg := 'Python 视觉超时');
State := 5;
END_IF
5: (* Sorting: NG 分拣 *)
IF CurBoard.InspectState = 3 THEN
ACT_NG_Cyl := TRUE;
TON_Timeout(IN := TRUE, PT := T#300ms);
IF TON_Timeout.Q THEN
ACT_NG_Cyl := FALSE;
TON_Timeout(IN := FALSE);
State := 6;
END_IF
ELSE
State := 6;
END_IF
6: (* Done: 写 MES + 归零 *)
CycleEnd := DT#NOW;
CurBoard.CycleTime_ms := UDINT(CycleEnd - CycleStart);
MES.UploadBoard(CurBoard);
ACT_Clamp := FALSE;
State := 0;
END_CASE
END_PROGRAM
8.2 Python 异步脚本桥接 (FB)
FUNCTION_BLOCK FB_PyAsync
VAR_INPUT
Script : STRING;
Method : STRING;
Arg1, Arg2 : POINTER TO BYTE;
END_VAR
VAR_OUTPUT
Done : BOOL;
Error : BOOL;
END_VAR
(* Darra 平台内置 PyBridge 实例调度, 脚本在独立协程池运行,
不阻塞 PLC 1ms 主周期。结果通过共享内存指针回传。
脚本文件变化 30ms 内热加载, 不重启 PLC。 *)
END_FUNCTION_BLOCK
8.3 Python 视觉脚本 (OpenCV + ONNX)
# scripts/aoi_inspect.py
# -*- coding: utf-8 -*-
import cv2
import numpy as np
import onnxruntime as ort
from darra import plc, log, camera
# 懒加载模型 (只加载一次)
_session = None
def _get_session():
global _session
if _session is None:
_session = ort.InferenceSession(
"scripts/aoi_model.onnx",
providers=["CUDAExecutionProvider", "CPUExecutionProvider"]
)
return _session
async def run(board_ptr, result_ptr):
"""主入口, 由 SCL 调用。异步协程, 不阻塞 PLC。"""
board = plc.read_udt(board_ptr, "UDT_AOI_Board")
# 1. 抓取相机最新帧 (零拷贝)
img_top = camera.grab("CamTop", timeout_ms=50)
img_bot = camera.grab("CamBot", timeout_ms=50)
if img_top is None or img_bot is None:
log.warn(f"[AOI] 相机取图失败 Board={board.BoardID}")
plc.write_int(result_ptr, 2) # NG
return
# 2. OpenCV 预检 (模板匹配 + 边缘检测)
defects = _rule_based_check(img_top, img_bot, board.Recipe)
# 3. ONNX 深度模型推理 (可疑区域二次确认)
if defects or _need_ai(board.Recipe):
ai_defects = _ai_inference(img_top, img_bot)
defects = _merge(defects, ai_defects)
# 4. 写结果
board.DefectCount = len(defects)
board.ImageTopPath = _save(img_top, board.BoardID, "top")
board.ImageBotPath = _save(img_bot, board.BoardID, "bot")
plc.write_udt(board_ptr, board)
plc.write_int(result_ptr, 1 if len(defects) == 0 else 2)
log.info(f"[AOI] Board={board.BoardID} Defects={len(defects)}")
def _rule_based_check(top, bot, recipe):
"""基于 OpenCV 的模板匹配 + 边缘检测。"""
tmpl = cv2.imread(f"templates/{recipe}_top.png", cv2.IMREAD_GRAYSCALE)
gray = cv2.cvtColor(top, cv2.COLOR_BGR2GRAY)
res = cv2.matchTemplate(gray, tmpl, cv2.TM_CCOEFF_NORMED)
# ... 逐元件比对 ...
return []
def _ai_inference(top, bot):
"""ONNX 模型推理缺陷定位。"""
sess = _get_session()
blob = cv2.dnn.blobFromImage(top, 1/255.0, (640, 640), swapRB=True)
outputs = sess.run(None, {"images": blob})
# ... 解析 YOLO 输出 ...
return []
def _save(img, bid, side):
path = f"D:/AOI/images/{bid}_{side}.jpg"
cv2.imwrite(path, img, [cv2.IMWRITE_JPEG_QUALITY, 85])
return path
def _need_ai(recipe): return recipe.startswith("HIGHREL_")
def _merge(a, b): return list(set(a + b))
热更新机制: 保存 aoi_inspect.py 时, Darra 脚本宿主监听文件变化, 30ms
内重新加载模块, 正在执行的协程跑完才切换, 业务无感升级。
8.4 机器人 3D 插补调用
(* 对位轴构成 "虚拟 4 自由度机器人" *)
Robot.TargetPose.X := Cur.PickX;
Robot.TargetPose.Y := Cur.PickY;
Robot.TargetPose.Z := Cur.PickZ;
Robot.TargetPose.C := 0.0;
Robot.MoveL(Vel := 400, Acc := 2000, Jerk := 20000);
(* 软限位保护 (防止撞镜头) *)
MC_SoftLimit(Axis := AxisZ, Min := -5.0, Max := 28.0);
9. 运行与调试
9.1 上电启动流程
- 上电后 PLC 运行
OB100: 伺服使能 + 回零 (X/Y/Z 逐一到机械原点) - HMI 主界面显示 "待机" + Robot 实时坐标
- 操作员选择配方 (产品型号), PLC 加载
CurRecipe - 按 "启动", 进入
Idle状态, 等来板触发
9.2 调试要点
| 环节 | 调试方法 |
|---|---|
| 相机硬触发延迟 | 用示波器同时观察 ACT_CamTrig_Top 与相机曝光信号, 应 < 0.5ms |
| 对位精度 | 标定板反复定位 100 次, 测 Cpk, 要求 > 1.33 |
| Python 脚本热更新 | 保存脚本, 观察 Darra IDE 日志 "Script Reloaded" 出现 |
| 视觉算法 | 用 IDE 的 "Python 交互" 窗口逐行执行, OpenCV 显示窗口调试 |
| MES 丢包 | 日志中 MES.UploadBoard 失败 → 自动持久化队列到 SQLite, 恢复后补传 |
| 节拍瓶颈 | HMI 显示各状态耗时直方图, 找最长状态优化 |
9.3 日志位置
| 日志 | 路径 |
|---|---|
| PLC 运行日志 | Darra IDE → 日志窗口, 按模块 AOI_Main 过滤 |
| Python 脚本 stdout | D:/DarraPLC/logs/py_*.log |
| MES 上传队列 | D:/DarraPLC/queue/mes_board.db |
| 图像留档 | D:/AOI/images/<BoardID>_top.jpg / _bot.jpg |
10. Darra 功能对照表
| 需求 | Darra 对应功能 | 说明 |
|---|---|---|
| 四轴对位 | 工艺对象 MC_MoveAbs + 3D 插补 | 内置, 不需外购运动卡 |
| 第三方视觉库 | Python 3.11 脚本宿主 | import cv2 / import halcon / import torch 自由 |
| 深度学习推理 | onnxruntime + GPU 透传 | 支持 CUDA / CPU 双后端 |
| 算法热更新 | 脚本宿主 FileWatch | 保存即生效, 不重启 PLC |
| 硬触发相机 | EtherCAT DC + DO 同步输出 | 延迟 < 0.5ms |
| MES 对接 | 内置 OPC UA + REST + SQLite 离线队列 | 无需第三方网关 |
| HMI 组态 | Darra HMI Designer | 静态按钮绑定 SCL 变量 |
| 配方管理 | 配方引擎 + JSON 持久化 | 支持版本控制 |
| 安全回路 | 硬接外部 Cat 3 安全继电器 | Darra 不做安全 PLC |
| 远程运维 | DarraSync 加密隧道 | 厂内算法团队可远程调试 |
| 数据追溯 | UDT + DT 时间戳 + SQLite | 每板 50+ 字段留档 90 天 |
11. 项目总结
11.1 交付成果
- 节拍: 3.1 s/pcs (目标 3.5, 超标 11%)
- 检出率: 99.7% (1000 片盲测)
- 误报率: 0.21% (目标 < 0.3%)
- 硬触发延迟: 0.42ms 实测
- 算法热更新: 保存到生效 28ms 平均, 业务不中断
11.2 关键技术点
- Darra 不内置视觉算法, 而是彻底开放 Python 协程宿主, 算法团队自由 选用 OpenCV / HALCON / PyTorch / PaddlePaddle / 自研 .so, 不锁厂
- 协程异步: 视觉推理 (耗时 50~120ms) 在独立协程池运行, PLC 1ms 主周期不受影响
- 硬触发同步: EtherCAT DC 分布时钟 + DO 输出到相机, 延迟 < 0.5ms
- 对位 = 虚拟机器人: XY/Z/θ 四轴由 Darra 3D 插补工艺对象驱动, 省运动卡
- 算法团队与机电团队解耦: 机电工程师负责 PLC + HMI, 算法工程师只改 .py
11.3 后续扩展方向
- 锂电池极片 AOI: 同平台复制, 只换视觉模型和光源
- 跨产品缺陷库: 多站数据汇总到 DarraCloud, 联合训练基础模型
- 低代码视觉流程: 规划中的
Darra Vision Flow, 拖拽组态替代部分 .py 编写
Darra 平台以**"控制器 + Python 脚本宿主"**双引擎架构, 让 AOI 工位的 运动控制稳如 PLC、视觉算法灵活如上位机, 两者在同一 IDE 下协同, 既解决了传统专机"算法闭源"的痛点, 又避免了"PLC + 工控机 + 视觉软件"三套系统的碎片化。