ABB机器人视觉通讯实战:Socket字符串解析与robtarget姿态修正
2026/9/23 22:56:06 网站建设 项目流程

简介:这份文档面向工业机器人与机器视觉方向的工程师及学习者,聚焦ABB机器人通过socket与相机视觉系统建立通讯的完整实现思路。内容围绕TCP/IP无协议通讯展开,涵盖socket客户端的创建与连接、字符串数据的收发、关键信息的提取,以及提取结果向机器人点位数据的转化,帮助读者打通视觉引导取放、定位补偿等典型应用中的数据链路。资源包为1个docx文档,约403KB,以图文步骤形式组织,便于对照示教器操作逐条理解。文档从socketCreate、SocketConnect到SocketSend、SocketReceive逐步说明,并演示如何用strfind、StrPart、StrToVal从“x,y,z\0D”格式字符串中解析出delta_x、delta_y、delta_theta,再借助eulerzyx与orientzyx将角度转换为四元数,最终更新robtarget点位。目前已有2361人学习下载,适合需要快速掌握ABB视觉通讯编程与数据解析技巧的读者参考。

1. 从一条字符串到一台机器人动作:ABB 视觉通讯到底在做什么

产线上常见的场景是这样的:一台工业相机拍完工件,把"1.23,4.56,7.89\0D"这样一串字符通过网口丢给 ABB 机器人控制器,机器人解析出 x、y 和 theta 三个偏量,再叠加到示教好的robtarget上,最后走一个带姿态修正的抓取点。整条链路里没有图像处理,也没有复杂的标定算法,真正容易翻车的是通讯握手、字符串解析和四元数姿态换算这三段。很多人第一次做 ABB 机器人视觉通讯,卡住的不是 socket 本身,而是StrPart的位号算错、eulerzyx反斜杠参数写反、或者robtarget忘了声明成VAR导致赋值静默失败。这篇把机器人当 client、相机当 server 的典型结构拆开讲,覆盖 socket 建立、字符串关键信息提取、偏量与robtarget的转化,适合正在做视觉引导抓取、涂胶、码垛定位的工程师对照复现。

2. socket 通讯建立:机器人做 client 端的完整指令链

2.1 为什么机器人通常做 client

在 ABB 视觉通讯里,机器人做 client、相机或上位机做 server 是最常见的分工。原因是相机侧一般跑在工控机或视觉控制器上,用 Python、C# 起一个监听端口比在示教器里改 IP 方便得多;而机器人侧只需要知道 server 的 IP 和端口,用SocketConnect主动连过去即可。这种结构下,机器人不需要开放端口,网络配置也更简单。

前提条件有两个必须先确认。第一,机器人系统里要带616-1 PC-Interface选项,没有这个选项SocketCreateSocketSend这些指令根本不会出现在指令列表里。第二,网线插 Service 口或 WAN 口都行,Service 口 IP 固定为192.168.125.1,WAN 口可以自己设。如果是在电脑上跑虚拟控制器做联调,server 的 IP 直接写127.0.0.1,端口自定义,别用 1025 这种容易被占用的默认值。

2.2 建立连接的指令顺序

下面这段是机器人侧建立 socket 并完成一次收发的骨架,可以直接抄进 RAPID 例行程序里改:

VAR socketdev socket1; VAR string send_data; VAR string recv_data; VAR rawbytes raw_data; PROC socket_client_demo() ! 先关闭可能残留的连接,避免端口占用 SocketClose socket1; ! 创建 socket 设备 SocketCreate socket1; ! 连接 server,IP 和端口按实际相机侧填写 SocketConnect socket1, "192.168.125.100", 5000; TPWrite "socket client connect successful"; ! 发送字符串给 server send_data := "1.23,4.56,7.89" + "\0D"; SocketSend socket1 \Str := send_data; ! 接收 server 返回的数据 SocketReceive socket1 \Str := recv_data; TPWrite "recv: " + recv_data; SocketClose socket1; ENDPROC

逻辑上分四步:SocketClose是防御性动作,上一次程序异常退出时连接可能没释放,不先关掉再SocketCreate会报错;SocketCreate只是创建一个 socket 设备变量,还没连出去;SocketConnect才是真正握手,这一步如果 server 没起来,机器人会一直停在这里等待,不会往下走,所以调试时先确认相机侧监听已经起来;SocketSendSocketReceive负责收发,\Str表示按字符串收发,如果要发字节数组就换成\RawDatarawbytes变量。

2.3 收发参数与常见坑

指令关键参数说明
SocketCreatesocketdev 变量必须先声明VAR socketdev,不能复用未关闭的变量
SocketConnectIP、端口端口要和 server 监听一致,虚拟联调用 127.0.0.1
SocketSend\Str\RawData字符串带结束符,字节数组用于二进制协议
SocketReceive\Str\RawData阻塞式,收不到会一直等,必要时配超时
SocketClosesocketdev 变量每次程序结束都要关,否则下次连接失败

几个实际会踩的点:SocketReceive默认是阻塞的,如果相机侧发完就不发了,机器人会卡死在这一行,常见做法是在相机协议里约定固定长度或固定结束符,收到结束符就返回;字符串拼接时"\0D"是回车符,RAPID 里写"\0D"而不是直接敲回车;如果连接一直失败,先ping一下相机 IP,再看相机侧防火墙有没有拦端口。TPWrite写屏是调试期最省事的验证手段,连上、收到数据都能在示教器上直接看到。

3. 字符串关键信息提取:strfind 与 StrPart 的位号计算

3.1 相机数据格式的约定

相机发过来的典型格式是"1.23,4.56,7.89\0D",逗号分隔三个数值,\0D作为结束符。机器人要做的就是把这三个数分别抠出来,转成num赋给delta_xdelta_ydelta_theta。核心思路是用StrFind找到每个分隔符的位置,算出每段子串的起始位和长度,再用StrPart截取,最后StrToVal转数值。

3.2 位号计算的实现

VAR num startbit1; VAR num endbit1; VAR num lenbit1; VAR string s1; VAR num delta_x; VAR bool ok1; PROC parse_vision_data(string recv_data) ! x 从第 1 位开始 startbit1 := 1; ! 找第一个逗号的位置,即 x 的结束位 endbit1 := StrFind(recv_data, 1, ","); ! 长度 = 结束位 - 起始位 lenbit1 := endbit1 - startbit1; ! 截取 x 的子串 s1 := StrPart(recv_data, startbit1, lenbit1); ! 字符串转数值,ok1 为转换结果 ok1 := StrToVal(s1, delta_x); IF ok1 THEN TPWrite "delta_x = " + NumToStr(delta_x, 3); ENDIF; ENDPROC

StrFind的第二个参数是搜索起始位,返回第一个匹配字符的位置;StrPart的三个参数分别是源字符串、起始位、长度,注意长度是字符个数不是结束位,所以要先减。StrToVal的返回值是bool,转换成功为TRUE,失败为FALSE,实际项目里一定要判断这个返回值,否则相机发来异常格式时delta_x会保留旧值,机器人会按错误偏量动作。

3.3 y 和 theta 的递推提取

x 提取完后,y 的起始位是endbit1 + 1,再找第二个逗号作为 y 的结束位,theta 同理找第三个逗号或结束符。把这段逻辑封装成一个函数,传入起始位返回下一个分隔符位置,代码会干净很多:

FUNC num next_comma(string s, num from) VAR num pos; pos := StrFind(s, from, ","); IF pos = 0 THEN ! 没找到逗号,说明是最后一段,用结束符位置兜底 pos := StrFind(s, from, "\0D"); ENDIF RETURN pos; ENDFUNC

这样三段提取就是同一套逻辑循环三次,位号不会算乱。实际调试时把每段的startbit1endbit1lenbit1TPWrite出来,对照原始字符串数一遍,比盯着代码猜快得多。

4. 偏量与 robtarget 转化:eulerzyx 与 orientzyx 的姿态换算

4.1 为什么不能直接改 robtarget 的 xyz

相机给的是平面偏量 x、y 和旋转角 theta,而 ABB 的robtargettrans(xyz)和rot(q1-q4 四元数)组成。位置部分好办,直接把偏量加到trans.xtrans.y上;姿态部分不能直接加角度,因为rot是四元数,得先把原姿态转成欧拉角,加上 theta 后再转回四元数。这就是eulerzyxorientzyx这对函数存在的原因。

4.2 从示教点到修正点的完整流程

假设Target_10_ini是在workobject_1下示教的基准点,通常示教在坐标系零点,workobject_1和相机坐标系一致(相机通过棋盘格标定纸标定对齐)。修正流程如下:

VAR robtarget Target_10; VAR num or_x; VAR num or_y; VAR num or_z; VAR num delta_x; VAR num delta_y; VAR num delta_theta; PROC correct_target() ! 取原点的姿态欧拉角,反斜杠参数指定输出哪个轴 or_x := EulerZYX(\X, Target_10_ini.rot); or_y := EulerZYX(\Y, Target_10_ini.rot); or_z := EulerZYX(\Z, Target_10_ini.rot); ! 位置偏量叠加 Target_10 := Target_10_ini; Target_10.trans.x := Target_10_ini.trans.x + delta_x; Target_10.trans.y := Target_10_ini.trans.y + delta_y; ! 角度偏量叠加到 z 轴 or_z := or_z + delta_theta; ! 欧拉角转回四元数姿态 Target_10.rot := OrientZYX(or_x, or_y, or_z); ENDPROC

EulerZYX每次只能取一个轴,靠反斜杠\X\Y\Z指定,这点和很多人的直觉相反,不能一次拿到三个角。OrientZYX则是反过来,把三个欧拉角合成四元数。Target_10必须声明成VAR robtarget,如果声明成CONSTPERS之外的只读类型,赋值会失败且不一定报错,这是很隐蔽的坑。

4.3 坐标系对齐与验证

workobject_1和相机坐标系对齐是整条链路精度的基础。常见做法是用棋盘格标定纸,相机识别角点算出像素到物理坐标的映射,机器人侧把workobject_1的原点示教到同一个物理基准点上。验证时先让相机发"0,0,0",机器人应该走到和Target_10_ini完全一致的位置;再发一个已知偏量,用示教器看实际位置和理论值差多少。如果偏差随距离线性增大,多半是坐标系没对齐或标定尺度不对;如果偏差固定,检查workobject_1原点示教精度。

5. 联调排错与超时保护:让视觉通讯在产线上稳得住

5.1 阻塞接收的超时处理

SocketReceive默认阻塞,产线上相机偶尔漏发一帧,机器人就会卡死。稳妥的做法是给接收加超时,或者约定固定长度协议。RAPID 里可以用SocketReceive配合\Time参数设置等待毫秒数,超时后返回错误码,程序据此走异常分支而不是死等:

VAR num recv_status; SocketReceive socket1 \Str := recv_data \Time := 2000; ! 超时或异常时 recv_status 非零,走重连或报警 IF recv_status <> 0 THEN TPWrite "recv timeout, retry"; SocketClose socket1; SocketCreate socket1; SocketConnect socket1, "192.168.125.100", 5000; ENDIF

超时后重连比原地重试更可靠,因为连接可能已经处于半开状态,直接再SocketReceive往往还是失败。

5.2 数据校验与异常兜底

相机发来的字符串不一定每次都合法,StrToVal返回FALSE时要有兜底。常见做法是维护一个有效标志,解析失败就跳过本次修正,机器人走原示教点或报警停机,绝不带着旧偏量动作。另外可以在协议里加校验位,比如末尾加一个累加和,机器人侧算一遍对比,能挡掉大部分传输错误。

5.3 联调顺序建议

按这个顺序调,能少走很多弯路:先用电脑起一个最简单的 TCP server 打印收到的内容,确认机器人能连上、能发出去;再让 server 回一个固定字符串,确认机器人能收到并写屏;然后接真实相机,先只看原始字符串,确认格式和结束符;最后才打开解析和点位修正。每一步都用TPWrite把中间变量打出来,比一次性全开再猜哪里错高效得多。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询