Skip to main content

端侧装配质检方案:缺件、尺寸判定与 Modbus / MQTT 输出

使用须知

尺寸结果按标定物换算像素得到,不能替代验收环节里经过校准的量具;随包检测器训练在裸板缺陷数据集 DeepPCB 上,它的六类缺陷不是装配缺件,用于自己的产品前要换成自己的期望件清单并用自己的数据实测。

这套方案是干什么的​

一台固定相机对着一个检测工位。每一帧先过检测器,再做缺件比对和尺寸测量,合并成一个 OK/NG 判定,按产线节拍输出。

  • 缺件比对——模板期望件清单(class + ROI + 匹配距离)与检测结果比对。清单里有、画面里没有的记为 missing;清单外找到的可选报为 extra。
  • 尺寸测量——与被测面共面的标定物给出 mm_per_pixel;测量 ROI 内目标的最小外接矩形换算成毫米,与名义尺寸 ± 公差比较。
  • 判定合并——defect、missing、extra、dimension_out_of_tolerance 任一成立即判 NG,四条可以逐条关闭。

判定同时写到两处:给 PLC 的 Modbus TCP 保持寄存器与线圈,以及给 MES 或历史库的每帧一条 MQTT JSON 事件。寄存器先于线圈写入,按线圈动作的 PLC 读到的寄存器就是同一次判定的数据。

  • 设备开箱即用

    reComputer J30 / J40 系列或 R2000 系列装好应用包即可运行,首次安装约 60 分钟;在 J40 系列上实测取图到线圈 P50 10.92 ms。

  • 代码开源

    运行时代码 Apache-2.0;检测器用 YOLOX-Tiny(Apache-2.0),不含 Ultralytics 代码与权重,没有 AGPL 义务。

  • 自有相机、PLC、MES 直接接入

    RTSP / ONVIF / USB 相机均可;判定走 Modbus TCP 与 MQTT。HR 0–7 与表面质检方案的寄存器布局相同,已有 PLC 程序不用改。

  • 全程本地运行

    取图、推理、判定、输出都在质检主机上完成,主链路不需要外网。

真机演示画面​

下面几张图是这条流水线的实际输出:

  • 检测器在一张 DeepPCB 验证图(12300060_test.jpg)上的输出,每个框都是 ONNX 模型的检测结果。随包示例配置里六条的期望件清单就是用这一帧的真值框生成的。
  • 名义尺寸下的合成 ArUco 场景:左侧标定物给出 mm/px,右侧目标按它换算(60 × 40 mm,判定 OK)。
  • 同一场景下的超差件:名义 60 mm、公差 1 mm,量到 62.25 mm,判定 NG,Modbus HR 10 = 6225、HR 11 = 2。

检测器在 DeepPCB 验证图上的输出:

检测器在 DeepPCB 验证图 12300060_test.jpg 上的输出,框为模型真实检测结果
同一模型在另一张 DeepPCB 验证图上的输出

尺寸链路:左侧标定物给出 mm/px,右侧目标按它换算。名义尺寸下判 OK:

名义尺寸下的合成标定场景:左侧标定物给出 mm/px,右侧目标量到 60 × 40 mm,判定 OK

同一场景放一个超差件,量到 62.25 mm,判 NG,Modbus HR 10 = 6225、HR 11 = 2:

超差件:名义 60 mm、公差 1 mm,量到 62.25 mm,判定 NG

目标旋转 25° 时,最小外接矩形给出同一个尺寸:

目标旋转 25° 后,最小外接矩形换算出的尺寸不变

尺寸场景由 evaluation/make_dimension_fixture.py 按已知 mm/px 合成,真值来自生成参数,不是真实工位照片。

需要哪些硬件​

一个工位三样东西:相机、质检主机、接收判定的系统。

① 相机——任意 RTSP 或 ONVIF 摄像头,USB 摄像头或录制文件也可以。型号不限,要求整块板或整件装配体在画面内,并且建模板后取景不再变。

② 质检主机——决定一台主机能接几个工位。

质检主机加速器当前下发的检测器实测路数什么时候选它
reComputer J3011reComputer J3011(Orin Nano 8GB)
单工位质检主机
Orin GPUYOLOX-Tiny 640²,TensorRT FP16单路,67 h 长稳单个工位
reComputer J4012reComputer J4012(Orin NX 16GB)
多工位聚合质检主机
Orin GPUYOLOX-Tiny 640²,TensorRT FP168 路稳定 / 12 路下降 / 24 路失败一台主机接多个工位;精度与速度数据都在这个模组上实测

多路容量:每路 640² / 10 fps,每级跑 5 分钟,整轮跑两遍,测试期间 MQTT 与 Modbus 关闭。两个出口都开时,可带路数低于 8。

两款 reComputer 都有无风扇工业形态(reComputer Industrial J3011 / J4012),模组与运行时相同,可装进控制柜。

③ 其余条件——做尺寸判定需要一个与被测面共面的标定物(ArUco 标记,默认 DICT_4X4_50,或任意已知宽度的参考物);相机与主机之间走以太网;再加一个 Modbus TCP 主站(PLC)和/或 MQTT 消费方。主链路不需要外网。

选型排他边界​

  • 单工位 vs 多工位:J3011 面向单工位单相机质检;若单台主机需要同时承载多个检测工位(>2 路并发)或高帧率拍摄,建议选配 J4012。
  • 模型动态下发与在线调优:Hailo-8 方案需在设备外编译固化模型文件,若现场需要高频直接在线微调或直接加载 PyTorch/ONNX 动态模型,应优先选择 Jetson 系列。

现场怎么部署​

先固定相机和光学,再装软件。

一、装硬件:先固定相机​

相机装好后不要再动

期望件 ROI 按画面坐标保存。相机移动、重新安装或重新对焦后,整份 assembly.expected[] 模板都要重建。产线上动过相机,就给这个工位重建模板。

整块板或整件装配体要在画面内。做尺寸判定时,标定物放在与被测面相同的平面上;工作距离不同会直接变成测量误差,系统不会报错。没有标定物时,尺寸段报 uncalibrated、Modbus HR 11 = 4,不输出数值。

二、装软件​

逐设备的操作步骤在可部署方案页,按现场条件选完配置后可以直接下载对应的应用包。


两条路径流程相同:

  1. 选套餐与主机。 摄像头 + reComputer J30 / J40(Orin) 或 摄像头 + reComputer R2000 系列(Hailo-8)。难度为高级,首次安装预留约 60 分钟。
  2. 部署质检运行时(必需)。Orin 路径首次部署时在设备上构建 TensorRT engine,约 5 分钟,engine 与这台设备、这个 TensorRT 版本绑定。Hailo 路径的 INT8 HEF 在设备外编译、部署时下载,板上不用构建,但要满足三个前提:Python 次版本匹配;HailoRT 4.21.x 的驱动、用户态库、Python 绑定三处版本一致;内核参数 hailo_pci force_desc_page_size=4096。
  3. 配置尺寸标定(可选)。不配置时缺件链路照常运行,尺寸段报 enabled: false 或 uncalibrated。
  4. 看判定结果(可选)。8080 端口的本地 Web 面板显示健康计数、最近事件,以及带检测框与缺件 ROI 的 MJPEG 预览。接 PLC 之前先在这里确认相机拍到了该拍的区域。
  5. 用 SAM2 标注工具生成期望件清单(可选)。工具跑在离线工作站上,不在边缘设备上,也不进帧循环;人工画框,SAM 2.1 Hiera-Small 生成像素 mask,再扩成装配 ROI。另有不需要 GPU 的 Otsu-flood 后端。

上线前把 assembly.expected[] 换成你自己的装配位。随包的期望件清单是用一张 DeepPCB 图生成的,只用于跑通链路。

有哪些接口​

数据从质检主机上三个接口输出,全部由主机本地提供。

  • 已经按 OK/NG 线圈动作的 PLC——读 Modbus TCP,端口 502、unit 1。HR 0–7 与表面质检方案 v1 的布局相同,已有程序不用改;新增信息在 HR 8–11。
  • MES 或历史库——订阅 1883 端口上的 <设备名>/inspection/<流编号>/results。每处理一帧一条 JSON 事件,schema 2.0.0,发布前做契约校验。
  • 操作工或调试工程师——8080 端口的 HTTP 面板。

<设备名> 在部署时填写,是主题的第一段,按产线、工段或工位命名,同一 broker 上的多台主机互不覆盖。流编号同时写在 payload 里,下游不必解析主题就能判断来源。

完整接口表​

类型位置内容备注
mqtt1883,<设备名>/inspection/<流编号>/resultsverdict、verdict_reasons、defect_count、detections[]、assembly(enabled、expected_count、matched_count、missing_count、extra_count,以及逐条缺失项的标签与 ROI)、dimension(enabled、calibrated、mm_per_pixel、out_of_tolerance_count、带逐项状态的 measurements[])schema 2.0.0;两段始终存在,模块在该路关闭时为 enabled: false
modbus_tcp502,unit 1,Coil 0/1 + HR 0–11Coil 0 = NG、Coil 1 = OK(互斥)。HR 0–7 同契约 v1:主缺陷类别、缺陷数、bbox ×10000、心跳。HR 8 = 缺件数,HR 9 = 多余件数,HR 10 = 测量 mm ×100,HR 11 = 公差判定码寄存器在同一把锁内先于线圈写入
http8080,/healthz /events /preview.mjpg帧率、推理耗时、缺件与尺寸失败计数;最近事件;带框与 ROI 的 MJPEG 预览本地面板,无鉴权

HR 11 公差判定码:0 ok、1 undersize、2 oversize、3 not_found、4 uncalibrated。

verdict_reasons 是列表,四条原因(defect、missing、extra、dimension_out_of_tolerance)可同时出现。ROI 按路配置(sources[].assembly 与 sources[].dimension)。用标注工具生成的 assembly 段带 roi_profile_sha256,标明现场跑的是哪一份 ROI profile;手写 ROI 时省略或为 null。

{
"schema": "2.0.0",
"device": "assembly-station-01",
"stream": "cam_pcb_top",
"timestamp": 1729000000.456,
"verdict": "NG",
"verdict_reasons": ["missing"],
"defect_count": 0,
"detections": [],
"assembly": {
"enabled": true,
"expected_count": 6,
"matched_count": 5,
"missing_count": 1,
"extra_count": 0,
"missing_items": [
{"label": "capacitor_c12", "roi": [120, 240, 160, 280]}
]
},
"dimension": {
"enabled": true,
"calibrated": true,
"mm_per_pixel": 0.125,
"out_of_tolerance_count": 0,
"measurements": [
{"name": "pcb_width", "value_mm": 60.05, "status": "ok"}
]
}
}

读字段时注意三点:

  • HR 10 = 0 时先读 HR 11。 3 和 4 表示没有可读的测量值,不是量到 0 mm。
  • v2 里 verdict = NG 时 defect_count 可以是 0。 有缺件或尺寸超差都会判 NG。
  • 线圈与寄存器只在写入侧是同一次采样。 线圈和寄存器分两个 Modbus 请求读时,在高判定率下可能读到两次判定的数据,约 20 次判定/秒时实测出现过。在意这一点就先轮询寄存器,把线圈当触发信号。

一台主机接多路时,Modbus 寄存器里是最近一次判定,可能来自任一路;逐路结果从 MQTT 取。包里的 MQTT broker 是本地匿名的,正式部署改为指向带凭据的 broker。

性能与实测数据​


速度与时延​

「检测器吞吐」只含检测调用;「全链路」含判定合并、Modbus、MQTT 与契约校验,不节流;「端到端」是节流到 10 fps 产线节拍时,从采集到写 Modbus 线圈。

设备模型 / 精度检测器吞吐全链路端到端 capture → Modbus 线圈
reComputer J40 系列(J4012,Orin NX 16GB)YOLOX-Tiny 640²,TensorRT FP1695.06 FPS(detect() P50 10.52 ms)89 FPS(P50 42.9 ms)P50 10.92 ms / P99 11.18 ms;3000 个样本,丢帧 0。整机从零部署(engine 在设备上构建)后:P50 9.81 ms / P95 10.18 ms,n=300
reComputer R2000 系列 + Hailo-8YOLOX-Tiny 640²,HailoRT INT8 HEF硬件 106.75 FPS(hailortcli run);应用层 94.02 FPS(P50 10.64 ms)43.92 FPSP50 11.89 ms / P99 16.08 ms

条件:Orin 检测器数字在 60 帧预解码画面上计时 500 次,其中 engine execute 约 6.3 ms,其余是 letterbox 加 CPU NMS。多路容量在 reComputer J40 系列(J4012)上实测:8 路稳定 / 12 路下降 / 24 路失败;每路 640² / 10 fps,每级跑 5 分钟,整轮跑两遍,MQTT 与 Modbus 关闭。reComputer J30 系列(J3011)单路 10 fps 连续运行 67 h,端到端 P50 11.45 ms。

复现:solutions/edge_inspection_assembly/evaluation/(Hailo-8:evaluation/runs/2026-09-06-rpi-hailo/results.md)

检测精度​

指标数值条件
mAP50,reComputer J40 系列,TensorRT FP160.9876DeepPCB6 val,205 图 / 1158 框 / 6 类;阈值 0.35 下 P 0.9284 / R 0.9741,FP 87 / FN 30,整帧漏检 0
mAP50-95,reComputer J40 系列(整机从零部署)0.8207同一 val 集;CPU 参考 0.8213
mAP50,reComputer R2000 系列 + Hailo-8,INT8 HEF0.9858同一 val 集;与 CPU 参考相比 −0.0018
mAP50,Hailo Dataflow Compiler 模拟器,INT80.992420 张 val 图 / 118 框,不与 205 图两行直接比较;CPU、native、quantized 三者 mAP50 / P / R 相同,逐框 CPU ↔ quantized 119/120 匹配

数据集 DeepPCB(MIT),六类(open / short / mousebite / spur / copper / pin-hole),不随包分发。

复现:solutions/edge_inspection_assembly/evaluation/(模拟器:evaluation/runs/2026-09-05-m3-hef/)

缺件与尺寸​

项目结果条件
缺件真值闭环模板帧 6 / 6 匹配;换板后 6 / 6 报缺失期望件清单由一张 val 图的真值框生成(ROI = GT 框 × 1.6,6 条);换板后 verdict_reasons 里 missing 与 defect 并列出现
尺寸误差(ArUco 标定)最差相对误差 0.65%,预算 1%合成 ArUco 场景,不含镜头与照明误差;长边 60 → 60.241 mm(+0.40%),短边 40 → 40.261 mm(+0.65%);公差 ±1.0 mm,判 ok;未压缩 PNG 与 mp4v 编码后数值一致
单路长稳67 h 连续运行,0 丢帧reComputer J30 系列(J3011),单路 10 fps;起跑基线 RSS 256–259 MiB,结温 61–62 °C,重启 0

复现:evaluation/make_dimension_fixture.py、evaluation/smoke_cpu_dimension.py;长稳档位 boundary.soak.yaml

运行时与关键参数​

设备模型精度运行时模型怎么到设备上
reComputer J30 / J40 系列YOLOX-Tiny 640²FP16TensorRT首次部署在设备上构建 engine(约 5 分钟),与该设备、该 TensorRT 版本绑定
reComputer R2000 系列 + Hailo-8YOLOX-Tiny 640²INT8HailoRT 4.21.xHEF 在设备外用 Hailo Dataflow Compiler 编译(optimization level 1 + Bias Correction),部署时下载
  • 检测阈值:0.35(评测配置)
  • 标定物:ArUco DICT_4X4_50(默认),或任意已知宽度的参考物
  • 判定原因:defect / missing / extra / dimension_out_of_tolerance 可逐条关闭;extra 需开启多余件上报

已知退化​

  • 相机移动、重新安装或重新对焦后,ROI 模板失效,要重建期望件清单。
  • 标定物与被测面工作距离不同、零件倾斜、边缘对比度低,会产生尺寸误差、not_found 或 uncalibrated,系统不报错。
  • 精度来自 DeepPCB 裸板缺陷,人造缺陷边界清晰,六类也不是装配缺件;真实装配场景更难。
  • reComputer R2000 系列的瓶颈在主机 CPU:全链路 43.92 FPS,相对检测器吞吐掉得比 Orin 多。
  • 多路数字在 MQTT 与 Modbus 关闭时测得,两个出口都开时可带路数低于 8。

数据与素材出处​

  • DeepPCB——github.com/tangsanli5201/DeepPCB,MIT 许可。用于训练随包检测器,也是上文所有精度数字的 val 集。MIT 许可允许再分发与商用,要求版权声明随副本与衍生作品一起传递,署名随包内 gallery/ATTRIBUTION.md 一起分发。图像是裸板铜箔层的二值化灰度扫描件,不含人物,也不含可识别客户的内容。数据集不随包分发。
  • YOLOX——github.com/Megvii-BaseDetection/YOLOX,Apache-2.0。检测器主干。不含 Ultralytics 的代码与权重,没有 AGPL 义务。
  • SAM 2.1 Hiera-Small——github.com/facebookresearch/sam2,代码与权重均为 Apache-2.0。只被离线标注工具使用。
  • 尺寸样例图——合成图像,由本项目的 evaluation/make_dimension_fixture.py 生成。不涉及第三方素材,无需署名。
  • 架构图——按设备目录与输出接口绘制。

运行时代码是 Apache-2.0。随包模型训练在 DeepPCB 上,适用范围见页首说明。

Loading Comments...