news 2026/10/11 7:55:18

海康 AGV 导航读码器学习

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
海康 AGV 导航读码器学习

一、产品说明

本产品主要应用于 AGV 小车定位导航,通过 AGV 导航传感器采集图像,并通过内部算法处理,解析画面中的二维码所代表的。

产品特性:

  • 内置读码算法,可高效读取 DM 码、码带和矩阵码
  • 内置色带定位算法,可高效定位色带位置
  • 算法鲁棒性强,可有效应对条码脏污、缺损、低对比度的情形
  • 选用优秀的 Sensor,图像质量优异,图像数据高速采集
  • 多指示灯用于调试和状态显示
  • M12 低畸变镜头,支持大视野读码定位
  • 优秀的光学设计,补光均匀,适应强反光场景

二、接口介绍与定义

设备接口为 12-pin P10 接口,提供供电、以太网和串口等功能,具体管脚信号定义如图 2-2、表 2-2 所示。

我使用的扫码器型号是MV-SC2005AM-02WBN AGV 导航读码器,他只能扫描地码,码带和色带是扫描不出来的。

三、相机的使用

本次实验就是使用扫码器识别地码,接线:(1)、用一根网线连接到电脑。(2)、接电源线,白色接24v,黑色接0v。

(1)、下载4.2.4版本的IDMVS软件

我第一次使用的版本是5.1版本的IDMVS软件,但是点击开始采集的时候会显示黑屏。就是相机识别不到图像。就像下边一样。

解决办法就是下载回4.2.4版本的IDMVS,但是有时后打开还是会黑屏,后面只需要重启一下设备就行了。

(2)、打开开始采集,就能看到图像了。

(3)、信息解读

右下角就的绿色部分就是扫描出来的关于码的信息了。

(3)、信息解读

<0007@(315.000x446.000)19.805@...@1-1-1>

这个就是相机的简单使用了,具体的参数调节可以看手册。

四、使用udp协议通讯接收相机的识别信息

(1)、IDMVS软件的设置

进入相机的设备树

(2)、找到传输控制

下面的这个就是数据传输的路径

(2)、编写py脚本接收并解析数据

#!/usr/bin/env python3 # -*- coding: utf-8 -*- """海康 MV-SC2005AM-02WBN 地码读码器 UDP 接收测试。 配置相机(IDMVS -> Transport Layer Control): Result Transfer Prototal = UDP Smart Udp Enable = On UDP Dst Addr = 192.168.20.55 UDP Dst Port = 1024 启动: python hikrobot_udp.py 结束: Ctrl+C 仅使用 Python 标准库。 说明:按照用户提供的《AGV导航读码器-客户版》UDP示例解析: HKVS 头、命令码、128 字节 ASCII 识别结果区域;不同固件可能有差异。 物理坐标二进制字段暂不按固定偏移强行解码,保存原始包供核对。 """ import argparse import re import socket from datetime import datetime from pathlib import Path MAGIC = b"HKVS" # 示例帧中:magic(4)+packet_id(4)+reserved(4)+command(4)+length(4)+timestamp(4) # +algorithm_ms(4)+flags(4)+info_length(4) = 36 bytes,随后128字节文本区。 ASCII_OFFSET = 36 ASCII_SIZE = 128 PATTERN = re.compile( r"<([^@<>]+)@\(\s*([+-]?\d+(?:\.\d+)?)\s*x\s*" r"([+-]?\d+(?:\.\d+)?)\s*\)\s*([+-]?\d+(?:\.\d+)?)" r"@([^@<>]*)@([^@<>]*)@([01]-[01]-[01])>" ) def parse_packet(data: bytes): """返回 (metadata, result, ascii_text)。解析失败 result 为 None。""" meta = {"size": len(data), "magic_ok": data.startswith(MAGIC)} if len(data) < ASCII_OFFSET or not meta["magic_ok"]: return meta, None, "" meta.update( packet_id=int.from_bytes(data[4:8], "big"), command=int.from_bytes(data[12:16], "big"), length_field=int.from_bytes(data[16:20], "big"), algorithm_ms=int.from_bytes(data[24:28], "big"), flags=list(data[28:31]), ) raw_text = data[ASCII_OFFSET:ASCII_OFFSET + ASCII_SIZE].split(b"\x00", 1)[0] ascii_text = raw_text.decode("ascii", errors="replace") match = PATTERN.search(ascii_text) if not match: return meta, None, ascii_text code, x, y, angle, cost, timestamp, flags = match.groups() return meta, { "code": code, "x_px": float(x), "y_px": float(y), "angle_deg": float(angle), "cost": cost, "timestamp": timestamp, "status": flags, }, ascii_text def main(): parser = argparse.ArgumentParser(description="海康 AGV 地码读码器 UDP 接收测试") parser.add_argument("--bind", default="0.0.0.0", help="监听IP,默认0.0.0.0") parser.add_argument("--port", type=int, default=1024, help="监听端口,默认1024") parser.add_argument("--camera-ip", default="192.168.20.99", help="相机来源IP;仅做提示,仍打印其它来源") parser.add_argument("--hex", action="store_true", help="每包打印完整十六进制") parser.add_argument("--all", action="store_true", help="打印每个包,默认只打印识别变化和每隔50包状态") parser.add_argument("--save", default="hikrobot_udp_packets.bin", help="保存原始包的文件名(长度前缀)") args = parser.parse_args() save_path = Path(args.save) count = 0 last_state = None with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as udp, save_path.open("ab") as dump: udp.bind((args.bind, args.port)) udp.settimeout(2) print("=" * 60) print("海康 SC2005AM UDP 通信测试(Ctrl+C退出)") print(f"相机IP预期:{args.camera_ip}") print(f"监听地址:{args.bind}:{args.port}") print(f"原始报文保存:{save_path.resolve()}") print("=" * 60) try: while True: try: data, (src_ip, src_port) = udp.recvfrom(65535) except socket.timeout: if count == 0: print("尚未收到数据:请检查相机UDP使能、目的IP/端口、防火墙。") continue count += 1 dump.write(len(data).to_bytes(4, "big") + data) dump.flush() meta, result, text = parse_packet(data) if args.hex: print(f"\nHEX {src_ip}:{src_port}({len(data)}字节):\n{data.hex(' ').upper()}") if result is not None: state = (result["code"], result["x_px"], result["y_px"], result["angle_deg"], result["status"]) if args.all or state != last_state: print(f"\n[{datetime.now():%H:%M:%S}] 来自 {src_ip}:{src_port},共收到 {count} 包") print(f"地码编号: {result['code']}") print(f"图像中心坐标: X={result['x_px']:.3f} px, Y={result['y_px']:.3f} px") print(f"地码角度: {result['angle_deg']:.3f}°") print(f"算法耗时: {result['cost']} ms | 时间戳: {result['timestamp']}") print(f"状态(定位-译码-ROI): {result['status']}") last_state = state elif args.all or count == 1 or count % 50 == 0: print(f"[{datetime.now():%H:%M:%S}] 第{count}包 来自 {src_ip}:{src_port} " f"长度={len(data)},magic={meta['magic_ok']} " f"命令={meta.get('command', '未知')},未匹配地码文本") if text: print(f"ASCII: {text[:180]!r}") if not args.hex: print("前64字节HEX:", data[:64].hex(" ").upper()) if src_ip != args.camera_ip and (args.all or count == 1): print(f"提示:收到的来源IP {src_ip} 与预期相机IP {args.camera_ip} 不同。") except KeyboardInterrupt: print(f"\n退出,共收到 {count} 包。原始报文已保存:{save_path.resolve()}") except PermissionError as exc: print(f"保存报文权限不足:{exc}") if __name__ == "__main__": main()

(3)、脚本运行结果

情况1:未识别到地码

[16:13:55] 第5600包 来自 192.168.20.99:8192 长度=268,magic=True 命令=1,未匹配地码文本 前64字节HEX: 48 4B 56 53 00 00 A7 9C 00 00 00 00 00 00 00 01 00 00 00 F8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [16:13:56] 第5650包 来自 192.168.20.99:8192 长度=268,magic=True 命令=1,未匹配地码文本 前64字节HEX: 48 4B 56 53 00 00 A7 CE 00 00 00 00 00 00 00 01 00 00 00 F8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [16:13:56] 第5700包 来自 192.168.20.99:8192 长度=268,magic=True 命令=1,未匹配地码文本 前64字节HEX: 48 4B 56 53 00 00 A8 00 00 00 00 00 00 00 00 01 00 00 00 F8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

情况2:识别到地码

[16:15:02] 来自 192.168.20.99:8192,共收到 359 包 地码编号: 0007 图像中心坐标: X=386.000 px, Y=427.000 px 地码角度: 62.071° 算法耗时: 06 ms | 时间戳: 001500ac 状态(定位-译码-ROI): 1-1-1 [16:15:02] 来自 192.168.20.99:8192,共收到 360 包 地码编号: 0007 图像中心坐标: X=387.000 px, Y=427.000 px 地码角度: 62.093° 算法耗时: 06 ms | 时间戳: 001500b8 状态(定位-译码-ROI): 1-1-1

经过脚本测试,相机一上电就开始识别是否存在地码了(一上电就工作了),不需要去IDMVS软件上点击开始采集。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/11 7:55:16

智诺方AI|硕士毕业论文长章节,局部改写兼顾降重与AIGC

智诺方AI&#xff5c;硕士毕业论文长章节分段优化思路&#xff0c;降重降AIGC避免长文本翻车&#xff5c;官网https://www.znfai.cn&#xff0c;微信服务号搜一搜 智诺方AI 硕士毕业论文篇幅长&#xff0c;动辄3万到5万字&#xff0c;很多同学修改论文时&#xff0c;图省事直接…

作者头像 李华
网站建设 2026/10/11 7:54:53

SWAT模型参数率定必知:PAWN与Sobol全局敏感性分析方法对比实战

全局敏感性分析入门&#xff1a;SWAT高参数化模型上PAWN与Sobol方法对比实战做水文模型的人&#xff0c;十有八九都被“参数敏感性分析”这件事折磨过。尤其是跑SWAT&#xff08;Soil and Water Assessment Tool&#xff0c;水土评估工具&#xff09;这类高参数化模型时&#x…

作者头像 李华
网站建设 2026/10/11 7:52:25

【单片机课设毕设项目】基于单片机的自行车里程测速定位采集与显示装置设计 基于物联网的骑行运动与位置追踪监测系统设计(030205)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机&#xff0c;Java、小程序技术领域和毕业项目实战 ✌️…

作者头像 李华
网站建设 2026/10/11 7:49:55

Selenium爬取天猫商品评论:异步加载、动态滚动与去重实战

做竞品分析想抓天猫商品评论&#xff0c;我第一反应是 requests 直接打接口。结果返回的 HTML 里根本没有评论数据&#xff0c;只有一个空壳。后来换成 Selenium 模拟浏览器&#xff0c;评论倒是出来了&#xff0c;可页面会自动加载&#xff0c;越滚越长&#xff0c;导出的数据…

作者头像 李华
网站建设 2026/10/11 7:49:27

Java程序员必看:掌握AI应用开发,薪资翻倍不是梦!

文章调研显示&#xff0c;成都地区60%的Java开发者转向AI应用开发&#xff0c;薪资普遍增长。通过学习AI技术&#xff0c;如Prompt Engineering、RAG等&#xff0c;可显著提升职业竞争力。文章分析了AI应用开发的核心技能要求及市场薪资水平&#xff0c;强调AI不是替代程序员&a…

作者头像 李华
网站建设 2026/10/11 7:49:03

iFlow CLI实测:在终端里对话式编程,多模型切换与免费边界

最近一个多月&#xff0c;我的日常写代码方式被一个叫 iFlow CLI 的命令行工具改变了。以前写个脚本&#xff0c;要么在浏览器里开好几个 AI 聊天页面来回复制粘贴&#xff0c;要么在编辑器里装一堆插件&#xff0c;每天光在不同工具之间搬运代码就花掉不少时间。现在我把大量编…

作者头像 李华