简介这份文档面向工业机器人与机器视觉方向的工程师及学习者聚焦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选项没有这个选项SocketCreate、SocketSend这些指令根本不会出现在指令列表里。第二网线插 Service 口或 WAN 口都行Service 口 IP 固定为192.168.125.1WAN 口可以自己设。如果是在电脑上跑虚拟控制器做联调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; ! 连接 serverIP 和端口按实际相机侧填写 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 没起来机器人会一直停在这里等待不会往下走所以调试时先确认相机侧监听已经起来SocketSend和SocketReceive负责收发\Str表示按字符串收发如果要发字节数组就换成\RawData配rawbytes变量。2.3 收发参数与常见坑指令关键参数说明SocketCreatesocketdev 变量必须先声明VAR socketdev不能复用未关闭的变量SocketConnectIP、端口端口要和 server 监听一致虚拟联调用 127.0.0.1SocketSend\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_x、delta_y、delta_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; ENDPROCStrFind的第二个参数是搜索起始位返回第一个匹配字符的位置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这样三段提取就是同一套逻辑循环三次位号不会算乱。实际调试时把每段的startbit1、endbit1、lenbit1都TPWrite出来对照原始字符串数一遍比盯着代码猜快得多。4. 偏量与 robtarget 转化eulerzyx 与 orientzyx 的姿态换算4.1 为什么不能直接改 robtarget 的 xyz相机给的是平面偏量 x、y 和旋转角 theta而 ABB 的robtarget由transxyz和rotq1-q4 四元数组成。位置部分好办直接把偏量加到trans.x、trans.y上姿态部分不能直接加角度因为rot是四元数得先把原姿态转成欧拉角加上 theta 后再转回四元数。这就是eulerzyx和orientzyx这对函数存在的原因。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); ENDPROCEulerZYX每次只能取一个轴靠反斜杠\X、\Y、\Z指定这点和很多人的直觉相反不能一次拿到三个角。OrientZYX则是反过来把三个欧拉角合成四元数。Target_10必须声明成VAR robtarget如果声明成CONST或PERS之外的只读类型赋值会失败且不一定报错这是很隐蔽的坑。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把中间变量打出来比一次性全开再猜哪里错高效得多。本文还有配套的精品资源点击获取
