ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ABB机器人Socket通讯实战:从RAPID代码到现场调试避坑指南

ABB机器人Socket通讯实战:从RAPID代码到现场调试避坑指南 在产线上调试视觉引导抓取工位时最常见的需求就是视觉系统计算出工件坐标通过网络发给机器人机器人走完位再回传一个完成信号。这类场景背后的核心交互就是socket通讯。ABB机器人的RAPID语言内置了一套完整的Socket指令集可以让机器人作为TCP客户端或服务器和PC、视觉系统、MES等设备直接交换数据。这篇文章就把我实际调试ABB机器人socket通讯的完整经验梳理出来从网络配置、RAPID代码怎么写、客户端和服务器模式怎么选到真机调试时会踩的坑一条条讲清楚。这篇文章适合正在做ABB机器人集成、需要和上位机或视觉系统做对接的工程师也适合在RobotStudio里做模拟验证、还没上真机的初学者。看完之后你应该能自己写出一套能用的socket通讯代码并且知道怎么调通它。1. 为什么ABB机器人和上位机通讯绕不开socket1.1 总线上解决不了的问题ABB机器人本身支持很多种现场总线比如Profinet、Devicenet、EtherNet/IP这些总线在和PLC通讯时非常好用数据映射到IO信号里梯形图里直接读写就行。但一旦涉及到和视觉系统、MES系统或者自己写的上位机软件通讯总线方案往往就比较别扭了。原因主要有几个。第一视觉系统通常跑在Windows或者Linux的工控机上不一定有总线通讯的硬件板卡和授权第二MES系统一般走以太网用工业总线协议去对接的成本很高第三你自行开发的上位机软件可能用的是C#、Python或者C做界面要它去实现Profinet从站协议开发难度和授权费用都比较高。socket通讯就是这时候的最佳选择。它走的是标准TCP/IP协议栈任何支持网络编程的语言都能对接不需要额外的硬件不需要授权只要机器人控制柜有网口上位机能ping通机器人控制器就能建立连接。1.2 哪些场景会用到socket通讯根据我接触过的项目ABB机器人socket通讯最常见的使用场景集中在下面几类视觉引导视觉系统算出工件在相机坐标系下的位置和角度通过socket发给机器人机器人做坐标转换后去抓取或装配MES数据交互机器人完成一个工位任务后把完工状态、数量、节拍等数据上传到MES系统同时接收MES下发的工单信息自定义上位机控制操作员在PC软件上点击按钮控制机器人的启停、程序选择和参数设置PC通过socket给机器人发指令机器人状态监控上位机定时向机器人发起请求获取当前坐标、报警信息、运行状态用于产线可视化大屏展示多台机器人协同机器人之间没有预留硬接线干节点时通过socket直接交换可以互锁信号和设备状态。1.3 ABB实现socket通讯的能力边界在动手之前先要弄清楚ABB机器人socket通讯的能力边界不然方案设计了半天到现场发现跑不起来就很尴尬。ABB的RAPID Socket指令在IRC5和OmniCore控制器上都支持RobotStudio仿真环境里也可以测试。每个任务最多支持4个socket连接也就是说一个机器人程序里可以同时维护多个客户端连接。通讯数据支持字符串和字节数组两种格式字符串适合发指令和简单数据字节数组适合传输二进制数据、图像数据或者和PLC的报文格式对齐。需要注意的一个点是ABBsocket通讯是标准的TCP协议它不是工业实时以太网不要拿它去传需要硬实时保证的数据。比如安全急停信号、伺服抱闸控制这些必须走硬接线或者安全总线socket通讯不能用来做安全功能。2. 写代码之前先把网络和硬件理清楚2.1 机器人控制柜的网口和IP配置ABB机器人控制柜一般有两个网口一个标着Service一个标着LAN/WAN。Service口通常用于和RobotStudio做在线连接默认IP是192.168.125.1。LAN口才是用来跑现场设备通讯的。配置IP的路径是在示教器上控制面板 - 配置 - 通信 - IP设置进入后选择对应的网口设置IP地址、子网掩码和默认网关在给机器人分配IP时建议直接用上位机去ping一下确认网络通了再往下写代码。这个步骤看起来简单但真很多人忽略。IP地址冲突、子网掩码不一致、网线插错口这些低级问题占了通讯调试失败原因的一半。2.2 网络拓扑怎么搭我调试过几种典型的网络拓扑分享给大家做参考。最简单的拓扑是点对点直连机器人LAN口直连电脑的网口IP设置在同一网段比如机器人192.168.1.10电脑192.168.1.20。这种方案干扰最少最便于排查问题。稍微复杂一点的拓扑是接入现场交换机机器人、视觉系统、上位机都插在同一个交换机上组成一个局域网。这种方案适合设备数量较多的产线。需要注意两层交换机就能满足要求不需要管理型交换机但IP规划一定要做表避免冲突。还有一种情况是机器人需要和跨网段的设备通讯这时候需要设置默认网关在上位机或者路由设备上做路由条目。不过说实话跨网段通讯在ABB机器人通讯场景里能避免就避免多一跳就多一个故障点IP规划阶段就尽量减少跨网段的需求。2.3 RobotStudio中的网络模拟RobotStudio仿真环境下测试socket通讯不需要真机这一点非常有用。仿真环境里机器人控制器的网络是直接映射到你的电脑网卡的也就是说你可以在RobotStudio里写RAPID程序同时在你自己的电脑上写一个Python或者C#的小工具来模拟上位机两者可以走真实的TCP通讯。这样做的最大好处是可以在不占用真机资源的情况下先把通讯协议和报文格式调试清楚。等程序下载到真机时通讯部分基本不用改动只需要确认真机IP配置正确即可。我自己习惯的做法是先搭一个Python的TCP模拟服务器在RobotStudio里跑机器人程序连上去把收发逻辑跑通再到现场直接验证。这样做能把调试时间压缩到原来的三分之一左右。3. RAPID里的socket指令把收发逻辑讲透3.1 核心指令清单ABB RAPID的socket通讯指令集中在Socket这个系统模块里最常用的就是下面这几条指令功能关键参数SocketCreate创建socket设备devSocketConnect作为客户端连接服务器dev, ip, portSocketSend发送数据dev, str/FileSocketReceive接收数据dev, strSocketClose关闭socketdevSocketBind绑定IP和端口dev, ip, portSocketListen监听连接devSocketAccept接受客户端连接dev, client_dev其中SocketCreate、SocketConnect、SocketSend、SocketReceive、SocketClose是客户端模式最常用的五条SocketBind、SocketListen、SocketAccept则是服务器模式额外需要的三条。SocketReceive有一个可选的\Time参数用来设置接收超时时间单位是秒。如果设置了超时时间在指定时间内没有数据到达指令会报错这时候配合错误处理语句可以做出超时判断逻辑。如果不加\Time参数SocketReceive会一直阻塞等待直到收到数据为止。3.2 客户端模式的完整代码框架先给客户端模式的一个完整示例机器人主动连接上位机发送一条请求指令然后等待上位机返回数据。MODULE SocketClient VAR socketdev client_socket; VAR string send_str; VAR string recv_str; PROC ClientMain() ! 创建socket SocketCreate client_socket; ! 连接服务器 SocketConnect client_socket, 192.168.1.100, 8080; ! 发送请求指令 send_str : GET_POS; SocketSend client_socket \\File:, str : send_str; ! 接收响应数据超时3秒 recv_str : ; SocketReceive client_socket \\Time:3, str : recv_str; TPWrite Received: recv_str; ! 关闭连接 SocketClose client_socket; ENDPROC ENDMODULE这段代码逻辑很清晰创建socket、连接、发送、接收、关闭。但这里有个细节值得注意SocketConnect是指令是阻塞式的如果对方IP不通或者端口没监听它会一直等待直到TCP连接超时通常几十秒。为了避免这个情况影响产线运行建议把连接超时时间也处理一下或者提前使用Ping指令确认网络可达。实际项目里面我不会把连接、发送、接收、关闭直接序列化写在主流程里而是拆封成独立的功能块。连接建立一次后保持长连接根据业务需要在需要时发送数据并接收响应不需要时再关闭连接。因为TCP建立连接的握手开销不小频繁打开关闭对通讯效率有影响。3.3 服务器模式的完整代码框架再看服务器模式的示例机器人作为服务端等待上位机连接接收数据并回馈状态。MODULE SocketServer VAR socketdev server_socket; VAR socketdev client_socket; VAR string recv_str; VAR string reply_str; PROC ServerMain() ! 创建服务器socket SocketCreate server_socket; ! 绑定端口0.0.0.0表示监听所有网卡 SocketBind server_socket, 0.0.0.0, 8080; ! 监听 SocketListen server_socket; ! 等待客户端连接这是阻塞操作 SocketAccept server_socket, client_socket; ! 接收客户端发来的数据 recv_str : ; SocketReceive client_socket \\Time:10, str : recv_str; TPWrite Received: recv_str; ! 回复客户端 reply_str : ACK; SocketSend client_socket str : reply_str; ! 关闭 SocketClose client_socket; SocketClose server_socket; ENDPROC ENDMODULE服务器模式在SocketBind的时候IP地址可以填具体的IP也可以填0.0.0.0表示绑定所有本机IP。对于只有一个网口的机器人来说两种写法差别不大但如果机器人有多个网口建议明确指定要监听的IP避免绑定错误。SocketAccept是阻塞式指令没有数据连接进来的时候程序就停在这里。如果你的主程序还有其他任务需要执行不要在一个任务里死等Accept可以考虑把Accept的逻辑放在独立任务里主任务持续监控其他逻辑。或者干脆用客户端模式让上位机作为服务器机器人主动发起连接。3.4 数据格式的选择字符串还是字节数组RAPID socket的SocketSend和SocketReceive有两种数据格式选项一种是通过str参数传递字符串一种是通过\File参数传递文件内容。字符串格式适合传输指令、坐标值等文本数据而文件传输通常用于传送较大的数据块。实际做视觉引导的时候我总结了一个报文格式约定指令用字符串数据量大的二进制数据用文件传输或者拆包传输。比如视觉系统给机器人发坐标直接发字符串X123.45Y67.89就行机器人端解析字符串提取数字如果是要传输一张轮廓点集可能几万个点那就直接用字节数组按照固定格式打包机器人端再解析。对于字符串解析ABB RAPID内置了很多字符串处理函数比如StrPart、StrFind、StrToVal可以很方便地从一串数据里提取数值。比如收到的报文是X100.5,Y200.3,Z50.0可以用StrFind定位逗号位置再用StrPart截取子串最后StrToVal转成num类型。有一点需要特别提醒ABB机器人里字符串类型在处理中文和特殊字符时会有编码问题RAPID的String默认是单字节编码如果上位机发送UTF-8编码的中文文本机器人端解析出来的会是一堆乱码。所以在设计通讯协议时要么所有报文都用英文和ASCII字符要么在项目中避免在socket数据里传输中文文本这是不少新手容易踩的坑。4. 客户端还是服务器?选型设计要结合现场4.1 两种模式的使用场景对比很多第一次做ABB socket通讯的人会纠结一个问题机器人到底应该做客户端还是服务器这个问题没有绝对的答案完全取决于现场的业务架构。我根据自己的项目经验整理了下面这张对比表维度机器人做客户端机器人做服务器主动发起方机器人主动连接上位机上位机主动连接机器人适用范围机器人需要向上位机请求任务或上报状态上位机需要集中管理多台机器人程序复杂度相对简单需要处理Accept阻塞问题上电重启后机器人程序重新启动后需要重新连接服务器端只需继续监听典型场景视觉系统给机器人发坐标MES系统集中采集多台设备数据4.2 视觉引导场景的选择逻辑以视觉引导抓取这个最典型的场景为例通常的做法是视觉系统作为服务器机器人作为客户端。视觉系统启动后先监听端口机器人运行到请求拍照位置后主动连接视觉系统发送一条CAPTURE指令视觉系统采集图像并计算出坐标后回传。这样设计的好处是机器人程序的控制权在自己手里想什么时候请求就什么时候请求。如果反过来让机器人当服务器视觉系统主动连接那么视觉系统需要处理机器人还没启动、端口还没监听的情况连接失败后还要考虑重连策略相对来说更为复杂。不过在有些项目里视觉系统需要同时给多台机器人发送工件坐标比如一条生产线两台机器人共用一个视觉系统。这时候让每台机器人各自去连接视觉系统视觉系统做服务器一个端口对应一台机器人这样也是可以的只要在协议里区分设备编号即可。4.3 连接管理策略在设计通讯逻辑的时候还有一个重要的选择长连接还是短连接。长连接就是建立一次TCP连接后一直保持需要通讯时直接收发数据。优点是连接建立一次就够没有反复握手的开销实时性好缺点是如果连接断了需要及时发现并重连。短连接模式是每次都建立连接、收发数据、然后关闭。优点是逻辑清晰不容易出现连接状态不同步的问题缺点是每次通讯都有握手开销而且频繁建立连接对TCP的TIME_WAIT状态处理不友好在连接频率高的场景下可能出现端口不够用的情况。我自己的经验是ABB机器人端优先用长连接。因为SocketReceive如果没有设置超时或者设置了较长的超时时间机器人程序会一直处于等待状态此时如果上位机重启了旧的TCP连接在机器人端还被认为是有效的但实际已经废了发送数据会失败。解决办法是加上超时时间超时后重新发起连接确保断开后能迅速重连。5. 一组血泪教训实测中那些坑与对应的出路5.1 超时问题是最隐蔽的坑SocketReceive不加\Time参数会一直等加了\Time参数超时后会报错。这个报错如果不处理整个任务就会停下来。所以稳妥的做法是用错误处理语句配合超时判断。RAPID的错误处理方式是CONNECT、ERROR、RETRY、RAISE这套逻辑。我在处理SocketReceive超时时的写法大致如下PROC SafeReceive() recv_str : ; SocketReceive client_socket \\Time:5, str : recv_str; ERROR IF ERRNO ERR_SOCK_TIMEOUT THEN TPWrite Receive timeout; recv_str : ; RETURN; ELSE RAISE; ENDIF ENDPROC这样如果接收超时程序不会停而是把recv_str置空返回调用处。上层逻辑再判断recv_str是否为空决定是否重发请求。5.2 粘包和分包问题TCP是字节流协议没有消息边界的概念。如果上位机连续发了多组数据机器人可能一次SocketReceive就把两包数据都取回来了反过来如果一包数据太长也可能需要分两次接收才能取完。这就是经典的粘包和分包问题。解决思路是在应用层协议里定义好自己的消息帧格式。我的做法是设计成帧头 数据长度 数据的格式。比如帧头固定为两个字节的0xAA55然后是四个字节的数据长度最后是数据内容。上位机按照这个格式发机器人端接收时先收帧头再读长度再按照长度把完整数据收完。不过复杂的一点在于ABB RAPID的字符串处理是面向字符的不是面向字节的处理二进制帧格式比较麻烦。如果只是传输ASCII文本用分隔符法就简单很多每条报文以换行符结尾机器人端接收后用StrFind找到换行符的位置按位置截取不足则继续接收这样也能有效避免粘包问题。5.3 系统重启和断线重连机器人断电重启后之前的socket连接全部失效。如果上位机还在傻傻地等着给机器人发数据那就会卡住。我建议在机器人启动程序里加一个连接状态检测机制启动后尝试创建socket并连接如果失败就重试每次重试间隔几秒直到连接成功为止。我踩过的一个坑是RobotStudio里调试好好的程序下载到真机之后发现机器人IP变了。排查下来是之前现场工程师把机器人IP改过但程序里面写的还是仿真时的IP。所以在真机调试时我养成了一个习惯把IP配置写在一个初始化模块里统一管理而不要硬编码在通讯程序的字符串里方便现场调整。5.4 bind失败和端口占用SocketBind时如果遇到address already in use之类的报错原因通常是上一次程序异常退出socket没有被正确关闭端口还处于占用状态。RAPID层面如果进程崩溃或者任务被强制停止socket资源可能没法及时释放。解决办法一般是把控制柜重启一次或者在SocketBind之前先尝试Sleep一会儿给系统足够的时间释放端口。另外如果你在RobotStudio里反复启动停止通讯程序也容易出现端口占用的情况此时重启仿真会话一般就能解决。6. 调试这套系统我的工作流和验证方法6.1 第一步Python模拟上位机先把通讯程序的主体逻辑搭起来然后用Python写一个小工具模拟上位机。这个方法对我来说是最高效的。Python不需要编译改起来快而且socket库是标准库开箱即用。下面是我常用的一个Python TCP服务器模板在电脑上跑起来就能当上位机模拟器用import socket server_socket socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server_socket.bind((0.0.0.0, 8080)) server_socket.listen(1) print(服务器监听8080端口...) conn, addr server_socket.accept() print(f机器人已连接: {addr}) while True: data conn.recv(1024) if not data: break print(f收到数据: {data.decode(utf-8)}) # 回一条ACK conn.sendall(bACK) # 收到EXIT则退出 if bEXIT in data: break conn.close() server_socket.close() print(服务器已关闭)把上面这段Python代码跑起来然后在RobotStudio里运行RAPID客户端程序就能看到机器人连接电脑、发送数据、收到ACK的完整过程。6.2 第二步RobotStudio里的仿真验证在RobotStudio里新建工作站添加一台ABB机器人然后在RAPID程序里编写socket通讯逻辑。仿真环境下机器人和电脑的IP是直通的不需要额外配置网络但要注意RobotStudio仿真环境有时候防火墙会拦截socket连接如果连不上检查一下Windows防火墙是否放行了对应端口。在仿真阶段多用TPWrite指令打印关键变量值。每做一步操作就打印一步比如连接成功打印Connected发送成功打印Sent: xxx接收成功打印Received: xxx。这些打印信息在仿真控制器的日志窗口里能看到对于快速定位问题帮助很大。6.3 第三步真机验证和现场巡检仿真通过之后下载到真机。真机调试时的重点和仿真不同仿真主要验证逻辑真机主要验证网络、IO配合和现场干扰。真机调试时我一般会按照下面的顺序逐项检查Ping确认上位机和机器人网络互通在示教器上手动执行客户端连接程序确认能连上上位机发送数据观察机器人是否能收到并正确解析机器人发送数据观察上位机是否收到检查长连接在长时间运行、多轮收发后的稳定性。现场环境里特别要注意的是电磁干扰对网线通讯的影响。如果现场有大功率伺服、变频器网线最好使用屏蔽双绞线并且和动力线缆分开走线。我在车间里就碰到过棘手的网络闪断问题排查到最后发现是网线跟伺服动力电缆扎在一起走的线缆分开后通讯立刻正常了——这类问题在网络拓扑、程序逻辑上都看不出任何异常必须在布线阶段就做好预防。6.4 加一个简易心跳机制在长连接场景下还有个非常值得做的事情——在通讯协议中增加心跳机制。因为TCP连接无法实时感知对端是否已经断开如果上位机突然断电或者程序崩溃机器人端如果不主动发送数据是感知不到连接已经断开的。心跳方案的实现方式不复杂机器人每2秒给上位机发一条PING指令上位机收到后回PONG。如果机器人连续三次没有收到PONG就认为连接已经断开主动关闭socket并重新发起连接。上位机也同样可以通过连续N秒收不到PING来判断机器人通讯是否异常。我之前有个项目就是因为没有心跳机制上位机重启后机器人还在等待旧连接的响应程序卡住不往下走了。后来加上心跳机制每次上位机重启机器人最多5秒内就能检测到连接失效并自动重连产线自动恢复运行不用人工干预这个问题就彻底解决了。7. 关于协议设计的最后几点建议报文格式的设计在socket通讯里太重要了排在没有好的报文格式的题越往后期越痛苦简单列一下我的约定习惯第一条尽量采用固定分隔符。我现在项目中用的比较多的是指令码,参数1,参数2这种CSV风格格式比如MOVE,100.5,200.3,50.0机器人端用StrFind和StrPart解析逻辑清晰排查报文时直接用文本工具就能看明白。第二条每条报文最后加一个结尾标记。比如加\n换行符上位机用readline函数接收机器人端用StrFind找换行符能有效避免粘包。第三条一定要做异常报文兼容。上位机和机器人收到的数据不一定是合法的解析失败不要直接报错停机而是记录日志并返回NACK给对端让对端决定是否需要重发这样整个系统会健壮很多。第四条版本号或者协议标识也别省。在报文开头加个简单的协议版本标识比如V1,MOVE,100.5,200.3虽然看起来有点多余但一旦后期升级协议兼容旧设备时你就知道这个字段的价值了。这些经验都是我一个个项目踩坑踩出来的。回到最开始那个视觉引导项目最终交付的时候光socket通讯相关代码也就一百行左右但前前后后调试了两天——一半时间花在梳理网络和端口问题上另一半时间花在纠错和适配报文格式上。所以说socket通讯本身不难难的是想清楚通讯双方之间的约定以及提前把各种异常情况都考虑进去。希望这篇文章能帮你在ABB机器人socket通讯上少走一段弯路。
返回列表