简介:DM二维码自动生成软件是一款面向AGV二维码导航场景的专用工具,专为倍加福读码器环境设计。二维码作为条形码的升级形式,具有信息密度高、容错能力强等特点,软件基于DataMatrix码制生成高精度二维码,可承载位置与路径信息,即使码面部分受损仍能可靠解译,保障自动引导车在工厂搬运、自动化仓储等场景下稳定定位。压缩包共10个文件,包含1个主程序exe、5个功能dll、2个xml配置、1个pdb调试符号及1个config配置文件,整体大小7.51MB,轻量易部署,其中dll支撑二维码生成与图像处理,xml与config管理运行参数与许可设置,便于离线安装和工业电脑部署。目前已有1756人学习下载。资源内附软件主体及配套运行组件,安装后即可生成二维码,并可通过倍加福读码器验证识别效果;同时,参考目录结构中的配置和调试文件,有助于理解此类工业读码软件的工作原理,快速适配AGV导航项目,适合自动化调试工程师、集成商及现场运维人员使用。
1. DM 二维码自动生成软件:AGV 贴码导航从「手动画图」到「批量出码」
做 AGV 项目的人都有过这种经历:规划好一条路径,地图上标了上百个站点,然后蹲在电脑前一个一个生成定位码、手动命名、排版打印,稍不留神文件名就和坐标对不上,到了现场码一贴,车直接跑偏。DM 码在 AGV 导航里并不是什么新鲜技术,但它始终是倍加福这类读码方案的地图基石——车间现场几十台 AGV 同时跑,靠的就是地上这些不起眼的小码。这篇笔记要讲的,就是一款面向 AGV 二维码导航场景的 DM 码自动生成软件:把坐标清单变成贴地码图,把容易错位的命名、排版、打印流程收成一条可复现的流水线。适合正在做 AGV 实施、产线调试、仓储物流规划的工程师,尤其是已经被手工生成码折磨过的人。
2. 为什么是 DM 码而不是常规二维码:两种码制的选型对比
2.1 Data Matrix 与 QR 码的技术差异:从定位图形说起
很多人一提到二维码,第一反应就是手机扫码用的 QR 码。但在 AGV 地面导航这个场景里,主流方案是 Data Matrix(DM 码),而不是 QR 码。两者的技术出发点就不一样:QR 码设计时考虑了手机摄像头的大众使用场景,有醒目的三个角定位框、较大的静区要求;DM 码则是为工业视觉优化过的,它的定位图形是一条 L 形实线加一条 L 形虚线,视觉上没那么醒目,但结构更紧凑。
这个差异直接决定了地贴码的面积和识读稳定性。同样的内容量,DM 码可以做得比 QR 码小 30% 到 50%。AGV 场地里码是贴在地上的,码越小,对地面平整度、清洁度的要求就越低,也不容易被叉车压坏。再加上倍加福 PGV 系列读码器原生就是按 Data Matrix 设计的,用 DM 码可以最大程度发挥读码器的识读能力。如果强行贴 QR 码,很多工业读码器要额外配置识别模式,识别距离和成功率都会下降。
选型时还有一点容易被忽略:DR 校正和运动补偿。AGV 在行进中读码,码是斜着经过读码器视野的。DM 码的稀疏型定位图形对姿态变化更宽容,在车辆以 1.5m/s 以上速度经过时,仍能稳定解算出横向偏移量。QR 码在这个场景下虽然也能读,但对帧率要求更高,经常出现连读失败。所以结论很直接:AGV 地面导航用 DM 码,不是因为二维码不行,而是 DM 码更合适。
下表是两种码制在 AGV 场景下的典型对比:
| 对比项 | Data Matrix(DM) | QR 码 |
|---|---|---|
| 定位图形 | L 形双实线,结构紧凑 | 三个回字定位框,占用面积大 |
| 相同内容的编码面积 | 约是 QR 的 50%~70% | 大 |
| 工业读码器适配 | 倍加福等品牌原生支持 | 需要额外配置识别模式 |
| 运动识读(车速 1.5m/s) | 稳定,姿态容错好 | 对帧率要求高,易丢帧 |
| 纠错能力 | 默认 ECC200,纠错级别可选 | 分 L/M/Q/H 四档 |
| 典型应用 | 自动化产线、AGV 导航 | 商品溯源、移动支付 |
2.2 决定读码成功率的核心参数:码尺寸、内容规范与静区
拿到软件后,第一步不是急着生成,而是先把三个参数定下来:单元尺寸、静区、码内容格式。这三个参数直接决定读码器能不能稳定工作,也是后面所有批量生成的基础。
单元尺寸指的是 DM 码中一个深色或浅色小格子的物理边长。码整体的边长 = 行数 × 单元尺寸。AGV 场景常见做法是单元尺寸 1.0mm 到 1.2mm,配 24×24 或 32×32 的矩阵,整体码面在 25mm~40mm 之间。这个尺寸不是拍脑袋定的,它取决于读码器的安装高度和视野宽度。倍加福 PGV 读码器离地高度通常在 40mm~60mm,视野范围是一条约 40mm 宽的条带,码过大反而在高速通过时扫不全,码过小则单元之间的对比度不够,识别距离直接缩短。
代码内容规范是另一个容易翻车的点。DM 码里存的不只是站点编号,还包括站点在地图里的坐标(X、Y、角度)。这样 AGV 经过码时,读码器不仅能定位,还能直接拿到全局坐标,不需要再去查表。常见内容格式是X:1200,Y:850,T:0,或者简化为1200,850,0。具体用哪种格式,取决于后台调度系统怎么解析,但无论在哪种方案里,内容都必须和地图坐标一一对应,且内容长度不建议超过 30 个字符串。
静区(quiet zone)是码四周必须留白的一圈空白区域,DM 码的静区一般要求不小于 1 个单元宽度。软件在导出图片时如果默认不带静区,打印出来边缘就会紧贴其他文字或深色边框,导致读码器找码困难。我一般建议导出时强制保留至少 2 个单元的静区,这样即使打印有轻微偏移,也不会触发边界误判。
2.3 生成第一个可用的 DM 定位码:Python 脚本实例
虽然软件自带图形界面,但从原理上理解生成过程仍然很有价值。这里用一个常见的 Python 库 treepoem 做演示,它底层调用 Zint 引擎,对 Data Matrix 的 ECC200 标准支持得很完整。
import treepoem # 生成 DM 码,内容为地图坐标,包含 X、Y 和角度 # barcode_type='datamatrix' 指定 Data Matrix 格式,默认走 ECC200 纠错 image = treepoem.generate_barcode( barcode_type='datamatrix', string='X:1200,Y:850,T:0', ) # 保存为 PNG,分辨率 300dpi,保证打印清晰 image.save('dm_1200_850.png', dpi=(300, 300))这段代码做的事情很简单:调用 Zint 引擎生成一个 Data Matrix 码,内容是一段坐标字符串。生成结果是一张黑白位图,但 Zint 默认不预留静区,所以后面打印排版时还需要在四周额外留白。这里我把分辨率明确设成 300dpi,因为打印头在低分辨率下会把单元边缘打糊,码面一旦发虚,读码成功率就往下掉。
参数层面需要注意几个点。datamatrix类型是 Zint 里对 Data Matrix 的标准实现,纠错级默认是 ECC200,不需要额外配置。string就是实际写入码的内容,AGV 场景下通常填坐标信息,内容里尽量避免用中文和特殊符号,因为部分读码配置对非 ASCII 内容的兼容性不好。代码跑出来后,先不要急着用,拿手机相机试扫一下能解出内容,再进入批量阶段。
3. 批量生成与地图输出:软件的操作流程和三个必须统一的规范
3.1 从 Excel 坐标导入到批量出码:操作步骤拆解
手工生成单个 DM 码不难,难的是让 200 个码的内容、文件名、地图坐标三者完全对得上。这套软件的核心价值就是把“手工对表”变成“导入即生成”。操作路径是:先整理站点坐标表,再导入软件,软件按预设规则生成码图并自动命名,最后导出打印排版文件。
坐标表通常是 Excel 格式,每一行代表一个站点。我建议的字段是:站点 ID、X 坐标、Y 坐标、角度、备注。其中 X/Y 的单位必须和地图坐标系统一,角度单位选度还是毫弧度,要提前和调度系统对齐。实际做过 AGV 项目的都知道,角度单位不一致是低级事故的高发区,有的调度系统用 360° 制,有的用弧度制,差一位小数结果就是车头转向偏了 5°。
坐标表整理完后,在软件里执行以下流程:
| 步骤 | 操作内容 | 需要配置的项 |
|---|---|---|
| 1 | 导入 Excel 坐标表 | 列名映射、表头行号 |
| 2 | 配置码内容模板 | 内容格式,如ID, X, Y, T |
| 3 | 配置码尺寸参数 | 单元尺寸、矩阵行列数、静区宽度 |
| 4 | 执行批量生成 | 输出目录、图片格式、命名规则 |
| 5 | 导出打印排版 | 纸张大小、每页码数、边距 |
这里最常见的习惯性错误是跳过第 5 步,导出散图到本地后直接用看图软件拼页打印。这样做既不安全也不高效,因为打印排版时缩放了尺寸,就会破坏单元的物理边长。正规流程是:软件直接输出用于打印的 PDF 或带精确毫米尺寸的 SVG,不在中途经过任何图片缩放。只要代码在软件里按真实物理尺寸排版,打印时选择“实际大小”输出,打印出来的码面尺寸才是准的。
3.2 批量生成脚本与命名规范:按行按列自动命名
为了不依赖 GUI,也可以用脚本理解批量生成的内部逻辑。以 treepoem 为例,读入 Excel 坐标表,循环生成码图,并按统一的命名规则输出文件。
import treepoem import pandas as pd from pathlib import Path df = pd.read_excel('agv_points.xlsx') out_dir = Path('output') out_dir.mkdir(exist_ok=True) for _, row in df.iterrows(): # 码内容模板:站点ID和X/Y坐标全部写入 content = f"{row['id']},{row['x']},{row['y']},{row['angle']}" # 生成码图 img = treepoem.generate_barcode( barcode_type='datamatrix', string=content, ) # 文件名规则:MAP_R{行}_C{列},列号补零到三位,方便排序 filename = f"MAP_R{row['row']:02d}_C{row['col']:03d}.png" img.save(out_dir / filename, dpi=(300, 300)) print(f"共生成 {len(df)} 个码,输出目录:{out_dir}")这段代码里,content就是码内的实际数据,row、col是地图网格的行列号,命名规则用行列号而不是坐标值,原因是行列号在调试时更好对应到地图上的网格位置。文件名补零是很多人容易忽略的细节:如果C1、C10、C100混在一起,文件管理器按字典序排序会乱。统一补零后,C001、C010、C100可以按自然顺序排列,检查时扫一眼就能看出缺了哪个。
生成完成后,不要把所有码图放在同一个文件夹里就不管了。我一般会再生成一个index.txt清单文件,内容是“文件名 TAB 码内容”的对照表。这个清单在现场调试时非常有用,一旦 AGV 在某站读出的坐标不对,拿着清单一对照就能定位问题出在生成环节还是写入环节。
3.3 打印与贴码尺寸的标定:倍加福读码器的视野计算
生成软硬件配合能否可靠工作,最终取决于打印出来的码面物理尺寸是否落在读码器视野范围内。这里有个计算公式,简单但特别关键:读码器视场宽度 = 安装高度 × 2 × tan(半视场角)。倍加福 PGV 系列的典型视场是安装高度为 50mm 时视野宽度约 40mm 到 50mm,具体数值以你手上那台的参数表为准。
码面尺寸必须满足:码的边长 + 2×静区宽度 ≤ 视场宽度。如果码面加静区接近视野上限,车辆经过时稍微偏一点就会出视野,识别率骤降;如果码面小于视野宽度的三分之一,码在画面里占的比例太小,对读码器的触发逻辑也不友好。所以最稳妥的区间是码面加静区占视野宽度的 50% 到 80%。
打印标定时我推荐一个土办法:生成一个测试码,量出码面纯黑区域的边长,再用尺子量一下打印出来的实际边长,两者误差应控制在 ±2% 以内。出现超过 5% 的偏差,基本可以断定打印选项里勾了“适应页面”或“缩放”,重新按 100% 实际大小打印就行,不需要怀疑软件数据。
4. 避坑记录:DM 码生成与贴地导航的五个翻车现场
4.1 现象:同一站点时灵时不灵,重打一张就好了
AGV 在某一个站点经常性识别失败,但把码重新打印粘贴后立刻恢复正常,过几天又复发。这通常不是软件问题,而是第一次打印时单元尺寸发生了偏移。很多打印机默认开启“缩放以适应页面”,如果码图边缘留白不足,打印机会自动把整个图缩到纸张可打印区域内,码的单元边长就被改变了。重打一张时如果人为调整了打印比例,恰好恢复了正确尺寸,于是“重打就好”的假象出现。
解决方法是打印时明确关闭“适应页面”,选择 100% 实际大小。另外在软件导出排版时,把静区宽度设置到 2 个单元以上,这样即使打印机有 1mm 左右的裁边误差,静区依然存在,不会让码边界贴到纸张边缘引起缩放判断。
4.2 现象:码打印出来边缘残缺,读码器直接无输出
打印出来的 DM 码四角发虚,L 形定位线不连续,读码器经过时完全无反应。原因基本指向两点:一是分辨率不够,码图只有 72dpi,打印头把每个单元渲染成模糊的灰块;二是纸张受潮或者墨粉不均匀,让浅色单元和深色单元的对比度低于读码器阈值。
解决方法是把导出分辨率统一提升到 300dpi,同时选用哑光不干胶纸,避免使用高光铜版纸。高光纸在反光时会让读码器误判对比度,车辆碾压后表面又容易出现划痕,划痕跨过定位线时就会直接吞掉一整个单元,最终结果是间歇性识别失败。
4.3 现象:坐标内容与文件名错位,AGV 跑到错误坐标
AGV 在某站读出的坐标和地图上的实际位置差了十几米,车直接停止报警。这类问题在手动生成码时最常发生,原因很简单:人眼对着 Excel 表一个一个生成,生成到中间某一站时串了一行,文件名还是对的,内容却用了下一行的坐标。这种错位非常隐蔽,因为码表面看起来完整,读出来也能解出数据,但数据本身是错误的。
解决方法是引入双向校验:生成完成后跑一遍解码,把每个文件的解码结果和 Excel 源表逐条比对,不一致的直接标红。现在很多生成软件内置了这个校验功能,但我建议即使有,也保留自己的脚本做一道独立验证。文本内容错位这类问题,任何一次人为介入都可能引入,独立校验是最有效的防线。
4.4 现象:码贴好后识别距离明显缩短
同型号读码器、同一批码,在 A 区域识别距离正常,在 B 区域缩水了一半。排除读码器硬件问题后,重点检查地面颜色和码周围环境。B 区域地面是深灰色水磨石,码的浅色单元和地面反射差异不大,读码器在找码阶段需要更长的曝光时间才能锁定图形。另一个常见干扰是旁边有黄黑相间的 safety 警示线,深黄和黑色交替的区域和 DM 码的边界在灰度图像里高度相似,读码器误锁定警示线区域,导致真正的码还没进入视野中心就被判失败。
解决方法是统一地面处理:在贴码位置先贴一块 100mm×100mm 的白色哑光底贴,再把 DM 码贴在底贴中央。底贴不仅解决对比度问题,还能减少地面裂缝对码的切割。需要特别注意的是,底贴不能有纹理,否则纹理在灰度图里也会变成噪声。
4.5 现象:整场验收读码率不足 95%,排查顺序混乱
整场 100 个站点验收,有六七站读码率不达标,现场组手忙脚乱换码重打,折腾一上午没效果。排查这类问题要有顺序,不能哪儿坏修哪儿。我见过最有效的顺序是:第一步确认读码器安装高度和角度没有变化;第二步确认码面物理尺寸,用尺子抽查几个识别失败的站点;第三步用解码工具读码内容,排除坐标错位;第四步才考虑重打重贴。
前两步排除了硬件和打印问题,第三步排除了数据问题,最后剩下的才可能是贴码位置偏差或现场遮挡。这个顺序能避免大量无效劳动,尤其是第一步,因为读码器支架在长时间运行后可能被叉车轻微碰到,高度变了 3mm,视野就偏移了,和码本身没有关系。
5. 收尾技巧:整图排版、解码核验与贴码前最后一道检查
5.1 把上百个码排进一张 A4:密度与留白的计算
批量生成的散图直接交给打印店排版,大概率会踩到缩放坑。我的做法是用软件或脚本把码按实际尺寸排进 A4,每页固定放若干个码,码与码之间留至少 5mm 的裁切间隔。A4 打印区域大约是 297mm×210mm,实际可用宽度按 280mm 算。假如码面加静区是 35mm,一页排 4 列、6 行,正好 24 个码,整场 192 个码就是 8 页纸。
排版文件必须用 PDF 或 SVG 导出,因为这两种格式自带物理尺寸信息,打开后只要确认没有缩放,打印出来的尺寸就是软件里设置的值。导出前,把每一页边缘印上页号和网格区间,例如Page 3/8,R6-C13 至 R9-C16,贴码时按页分区施工,效率能提升不少,也不会出现整页贴错方向的情况。
5.2 用 Python 解码批量核验:不贴码就能发现的错误
贴码前花五分钟跑一遍解码校验,能拦下大部分坑。这里用 zxing-cpp 库批量读取生成的码图,并把解码内容和文件名做成对照表。
import zxingcpp from pathlib import Path from PIL import Image for png in sorted(Path('output').glob('*.png')): img = Image.open(png) results = zxingcpp.read_barcodes(img) text = results[0].text if results else '(解码失败)' print(f"{png.name}\t{text}")这段代码的输出是一个文件名和解码内容的对照表。检查两个东西:一是每个文件都能解出内容,没有解码失败;二是文件名里的行列号和解码内容里的坐标能对上逻辑。比如文件名是MAP_R02_C005,码内容应该是行 2 列 5 对应的那个站点坐标,如果出现内容与文件名对应关系混乱,立刻回查 Excel 源表。
我自己的习惯是:每次批量生成完码,不管多么急,都把这道校验跑一遍再送去打印。这个习惯是从一次事故里换来的——有一回 300 多个码没校验直接上了现场,贴了两天才发现第 89 号站的码内容被写成了 90 号站的坐标,返工成本和耽误的时间远超生成环节节省的半小时。从那以后我每次批量出码,都强制走一遍解码核验流程,这比到了现场靠人眼一个个扫要可靠得多。希望你也能把这道检查固化到自己的流程里,希望帮到你。
本文还有配套的精品资源,点击获取