ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Nachi机器人TCP通讯实战:从协议原理到工业现场稳定集成

Nachi机器人TCP通讯实战:从协议原理到工业现场稳定集成 1. 项目缘起当工业机器人需要“开口说话”在自动化产线上机器人不再是孤立的“哑巴”执行者。一个常见的场景是一台Nachi机器人完成装配后需要将“已完成工件IDA123良品”这个信息告诉上游的MES系统或者接收来自视觉检测系统的指令“第3号工位抓取红色工件”。这种机器人与外部系统如PLC、PC、数据库、视觉系统之间的实时数据交换就是工业现场通讯的核心需求。TCP/IP通讯正是实现这种“对话”的通用语言。它不像机器人示教器编程那样局限于点位和轨迹而是打开了通往更广阔自动化世界的大门。通过TCP机器人可以发送字符串、数字、甚至文件接收复杂的生产指令真正融入智能制造的“神经网络”。我最初接触Nachi机器人TCP通讯是因为一个汽车零部件拧紧项目。客户要求机器人将每一颗螺丝的最终扭矩、角度和结果OK/NG实时上传到服务器进行质量追溯。示教器编程和IO点显然无法承载如此复杂的数据。在评估了多种方案后我们最终选择了基于TCP Socket的通讯方式。它不依赖特定的硬件模块如昂贵的通讯板卡直接利用机器人控制柜自带的以太网口通过标准的网络协议与服务器对话成本低、灵活性极高。这个项目标题“Nachi机器人TCP通讯”看似简单实则涵盖了从网络基础、机器人配置、程序编写到异常处理的全链路知识。它不仅是让机器人“联网”更是赋予其与整个生产系统协同工作的“智慧”。接下来我将结合实战经验拆解实现这一功能需要闯过的每一道关卡。2. 理解基石TCP协议在工业场景下的特殊考量在动手配置机器人之前我们必须先理解TCP协议本身以及它在工业控制环境下的特殊性。这决定了我们后续所有配置和编程的逻辑。2.1 TCP vs. UDP为什么工业通讯首选TCP网络通讯有两大主流协议TCP传输控制协议和UDP用户数据报协议。在消费互联网视频流、游戏可能用UDP追求速度。但在工业领域可靠性是压倒一切的首要原则。一个丢失的“急停”指令或一个错位的坐标数据可能导致严重的设备损坏或安全事故。TCP通过“三次握手”建立连接、数据包确认重传、序列号保证顺序等机制提供了可靠的、面向连接的字节流服务。这正是工业控制所需要的确保每一句“指令”都准确无误地送达并且顺序正确。而UDP是“尽力而为”的无连接协议不保证可靠和有序更适合对实时性要求极高且能容忍少量丢包的场景如某些传感器广播。注意在Nachi机器人乃至绝大多数工业机器人的通讯功能中其内置的Socket通讯指令通常只支持TCP客户端Client模式。这意味着机器人需要主动去连接作为服务器Server的PC、PLC或服务器。理解“客户端-服务器”模型是后续所有配置的基础。2.2 工业TCP通讯的典型数据格式字符串与字节流机器人控制器和外部系统交换的不是人类直接可读的文档而是一串串字节。我们需要约定一种双方都能理解的“语法”。纯字符串ASCII最常见、最易调试的格式。例如机器人发送“POS,100.0,200.0,300.0\n”表示一个位置坐标。接收方按逗号分隔解析即可。在Nachi的PacScript语言中可以方便地拼接和发送字符串。二进制数据效率更高节省带宽。例如将一个浮点数如100.0直接转换为4字节的二进制流发送。这需要发送端和接收端对数据类型的字节序大端/小端有严格约定编程更复杂但适合高频、大数据量传输。标准协议封装在字符串或二进制流之上套用成熟的工业协议如Modbus TCP。Modbus TCP规定了标准的功能码、数据地址和格式。如果对方系统如PLC支持Modbus TCP那么机器人侧实现一个Modbus TCP客户端通讯会变得非常标准化。不过Nachi原生指令可能不直接支持需要自己用Socket指令去组Modbus报文。在我们的扭矩上传项目中选择的是“字符串分隔符逗号结束符换行\n”的方式。因为它足够简单在PC端用Python、C#等语言可以轻松解析也便于在调试阶段通过网络调试助手直接查看。2.3 关键参数端口、超时与缓冲区端口号一个IP地址好比一栋大楼端口号就是大楼里的房间号。服务器的监听端口必须是一个未被占用的特定端口如5000。机器人作为客户端需要指定这个端口去连接。切记1024以下的端口通常为系统保留建议使用1024-65535之间的端口。超时设置网络是不稳定的。设置连接超时如5秒和接收超时如2秒至关重要。如果机器人在规定时间内连不上服务器或收不到回复程序应能超时退出并触发报警而不是永远卡住。缓冲区接收数据时需要一个临时的存储区缓冲区。需要根据可能接收的最大数据包长度来合理设置缓冲区大小避免数据截断。3. 实战配置Nachi机器人侧的Socket通讯设置Nachi机器人通常使用PacScript语言进行逻辑和通讯编程。其Socket通讯功能主要通过几个核心指令实现。以下配置基于常见的Nachi控制器具体指令名可能因软件版本略有差异但原理相通。3.1 网络基础配置让机器人拥有“身份证”机器人控制柜必须接入工厂局域网并拥有一个合法的IP地址。这通常在示教器的系统设置里完成。进入设置菜单在示教器上按下MENU-系统-网络设置。配置IP地址选择“TCP/IP”设置。这里通常有三种方式静态IP推荐手动指定IP地址、子网掩码、默认网关。例如设置为192.168.1.100。静态IP确保机器人地址固定不变便于服务器端始终连接同一个地址。DHCP从工厂的DHCP服务器自动获取IP。适用于大型网络但IP可能会变不利于稳定的服务器连接。注意务必确保机器人的IP与要连接的服务器IP在同一网段如都在192.168.1.x且网络物理连通网线、交换机正常。3.2 核心通讯指令详解与编程框架PacScript中用于Socket通讯的关键指令是SOCKET_OPEN,SOCKET_SEND,SOCKET_RECV,SOCKET_CLOSE。下面是一个最基础的客户端通讯程序框架并附上详细注释。PROGRAM Main VAR socket_id : INTEGER // 套接字ID用于标识一个连接 server_ip : STRING : 192.168.1.50 // 服务器IP地址 server_port : INTEGER : 5000 // 服务器端口 send_data : STRING // 要发送的数据 recv_data : STRING // 接收到的数据 ret : INTEGER // 用于存储指令返回值0通常表示成功 connected : BOOL : FALSE // 连接状态标志 END_VAR // 步骤1建立TCP连接 ret SOCKET_OPEN(socket_id, server_ip, server_port) IF ret 0 THEN connected TRUE WRITE TCP连接成功 socket_id: , socket_id ELSE WRITE TCP连接失败错误码: , ret ERROR // 触发机器人报警 RETURN // 退出程序 END_IF // 步骤2发送数据 send_data READY,ROBOT1 CHR(10) // CHR(10)是换行符\n作为结束标志 ret SOCKET_SEND(socket_id, send_data) IF ret 0 THEN WRITE 数据发送失败 // 这里通常需要加入重试或错误处理逻辑 END_IF // 步骤3接收数据等待服务器指令 // 先清空接收缓冲区 recv_data // SOCKET_RECV会阻塞直到收到数据或超时。超时时间可能在系统参数中设置。 ret SOCKET_RECV(socket_id, recv_data) IF ret 0 THEN WRITE 接收到指令: , recv_data // 解析recv_data例如判断是否是MOVE_TO_PICK IF FIND(recv_data, MOVE_TO_PICK) 0 THEN CALL Pick_Routine() // 调用抓取子程序 END_IF ELSE WRITE 接收数据失败或超时 END_IF // 步骤4关闭连接非常重要 IF connected THEN SOCKET_CLOSE(socket_id) connected FALSE WRITE 连接已关闭 END_IF END关键点解析SOCKET_OPEN此指令使机器人作为客户端发起连接。socket_id是一个输出参数连接成功后后续所有操作都基于这个ID。SOCKET_SEND发送字符串。务必注意字符串的编码和结束符。与服务器端约定好是否以换行符\n或特定字符如分号;作为报文结束标志这是避免“粘包”问题的简单方法。SOCKET_RECV这是一个阻塞式调用。程序执行到这一行会停止直到收到数据、连接断开或超时。这意味着你的机器人程序在等待指令时其他动作也会停止。对于需要一边运动一边等待指令的场景这个方案不适用需要考虑非阻塞或后台任务处理。SOCKET_CLOSE通信结束后必须关闭连接释放系统资源。养成“打开连接后必定安排关闭”的习惯。3.3 连接模式的选择长连接 vs. 短连接根据业务场景有两种主要的连接策略短连接一问一答每次需要通讯时执行OPEN - SEND/RECV - CLOSE。优点是逻辑简单服务器端压力小。缺点是每次建立TCP连接都需要“三次握手”有延迟开销。适合通讯不频繁的场景如每完成一个工件上传一次数据。长连接保持会话在程序开始时建立连接在整个作业周期甚至一整天内保持连接不断开循环进行SEND/RECV。优点是实时性高延迟小。缺点是需要处理网络异常断开后的重连机制且服务器需要维护大量并发连接。适合需要高频、实时交互的场景如实时跟随。在我们的拧紧项目中由于每颗螺丝拧紧后都需要上传数据频率较高约每秒1-2次我们采用了长连接。我们在机器人初始化例程中建立连接在结束或发生严重错误时才关闭。同时在每次SOCKET_SEND后都检查返回值并在发送失败时加入带延迟的重试逻辑和最终报警。4. 服务器端搭档以Python为例的简易测试服务器机器人端的程序写好了它需要和一个服务器“对话”。在项目前期调试和后期维护中用一个简单的脚本模拟服务器至关重要。这里用Python的socket库演示一个最基础的同步服务器。import socket import threading def handle_client(conn, addr): 处理单个客户端连接的函数 print(f[新连接] {addr} 已连接。) with conn: while True: # 接收数据缓冲区大小为1024字节 data conn.recv(1024) if not data: # 客户端关闭连接 print(f[连接断开] {addr}) break # 将收到的字节解码为字符串假设是UTF-8编码 message data.decode(utf-8).strip() # strip()移除末尾换行符 print(f[来自 {addr}] 收到: {message}) # 根据消息内容回复 if message.startswith(READY): response STATUS,OK\n elif message.startswith(TORQUE): # 解析扭矩数据例如TORQUE,ID001,22.5,OK parts message.split(,) if len(parts) 4: screw_id, torque, result parts[1], parts[2], parts[3] print(f记录数据螺钉{screw_id}, 扭矩{torque}Nm, 结果{result}) # 这里可以插入数据库 response DATA_RECEIVED\n else: response ERROR,FORMAT\n else: response UNKNOWN_CMD\n # 发送回复 conn.sendall(response.encode(utf-8)) print(f[结束] 与 {addr} 的连接处理完毕。) def start_server(host0.0.0.0, port5000): 启动TCP服务器 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 允许地址重用 s.bind((host, port)) s.listen(5) # 允许最多5个排队连接 print(f[启动] 服务器监听于 {host}:{port}) while True: conn, addr s.accept() # 等待客户端连接阻塞 # 为每个新连接创建一个线程处理实现并发 client_thread threading.Thread(targethandle_client, args(conn, addr)) client_thread.daemon True client_thread.start() if __name__ __main__: start_server()这个Python服务器的关键作用调试运行此脚本用机器人去连接它可以直观看到机器人发送过来的原始字符串验证数据格式是否正确。模拟可以模拟MES或PLC的行为给机器人回复预设的指令如“MOVE_TO_NEXT”测试机器人端的解析和响应逻辑。日志所有交互记录在控制台是排查通讯问题的第一手资料。实操心得在项目初期千万不要让机器人直接去连真实的MES或PLC。先用这样一个Python脚本作为“假服务器”把所有通讯逻辑调试通。这能避免因机器人程序问题对生产系统造成干扰也大大提升了调试效率。5. 避坑指南从实验室到产线的血泪教训理论连通只是第一步让TCP通讯在嘈杂的工业现场稳定运行才是真正的挑战。下面是我踩过的一些坑和总结的应对策略。5.1 连接不稳定与断线重连问题现象机器人运行几小时或几天后突然发送数据失败但网络物理上是通的。根因分析网络波动工厂内大功率设备启停、交换机故障等可能导致短暂网络中断。防火墙/杀毒软件服务器端的Windows防火墙或杀毒软件可能误杀长时间空闲的连接。NAT超时如果网络经过多层路由或NAT转换长时间无数据流路由器可能会清除连接映射表。解决方案实现心跳机制与稳健的重连逻辑心跳包在长连接中即使没有业务数据也定期如每30秒发送一个简短的心跳包如“PING”。服务器回复“PONG”。这既能保持连接活跃又能及时探测连接是否存活。重连逻辑在机器人程序中任何SOCKET_SEND或SOCKET_RECV失败后不应立即报警停产。应进入一个重连子程序FUNCTION TryReconnect : BOOL VAR retry_count : INTEGER : 0 max_retries : INTEGER : 3 END_VAR WHILE retry_count max_retries DO SOCKET_CLOSE(socket_id) // 先尝试关闭旧连接如果存在 WAIT TIME 2000 // 等待2秒 ret SOCKET_OPEN(socket_id, server_ip, server_port) IF ret 0 THEN TryReconnect TRUE RETURN END_IF retry_count retry_count 1 WAIT TIME 5000 // 失败后等待更久 END_WHILE TryReconnect FALSE // 重连失败 END_FUNCTION在主程序中调用此函数只有重连也失败后才触发严重报警。5.2 数据“粘包”与“拆包”问题现象服务器端一次recv收到了机器人发送的两条消息如“DATA1\nDATA2\n”或者一条消息被拆成两次接收。根因分析这是TCP字节流传输的特性决定的。TCP保证数据顺序但不保证应用层报文边界。网络底层可能会根据缓冲区情况合并或拆分数据包。解决方案定义应用层协议固定长度每条消息长度固定不足补位。简单但不够灵活。分隔符在消息末尾添加特殊字符作为结束标志如换行符\n。这是最常用的方法。务必确保你的消息内容本身不会包含这个分隔符。长度头在消息开头几个字节声明本条消息的长度。例如先发送4字节的整数表示后续数据长度再发送实际数据。这是最严谨的方式。在Nachi的字符串发送中强烈推荐使用“分隔符法”。在每条发送的字符串末尾加上CHR(10)换行。在服务器端按\n来分割接收到的字节流就能得到完整的单条消息。5.3 编码与字符集冲突问题现象机器人发送的中文或特殊字符在服务器端显示为乱码。根因分析机器人控制器和服务器可能使用不同的字符编码如ASCII, UTF-8, GBK。解决方案统一使用ASCII码进行通讯。这是最安全、兼容性最好的选择。如果需要传输非ASCII字符如中文双方需明确约定并使用同一种编码推荐UTF-8并在发送端进行编码接收端进行解码。在PacScript中处理非ASCII字符串需要格外小心。5.4 阻塞式接收导致的程序停顿问题现象机器人执行到SOCKET_RECV时整个程序停住机械臂也不动了直到收到数据。根因分析如前所述SOCKET_RECV是阻塞调用。解决方案场景一允许等待如果工艺要求就是停下来等指令那么这是合理行为。但务必设置合理的接收超时参数在系统配置中查找避免因服务器宕机导致机器人无限期等待。场景二需要后台接收如果机器人不能停需要一边运动一边“听令”这就复杂了。一种思路是利用机器人的后台任务功能。创建一个低优先级的后台程序专门循环执行接收指令并将接收到的指令存入一个全局变量或队列。主程序定期去检查这个全局变量是否有新指令。这需要对机器人的多任务编程有较深理解。替代方案考虑使用机器人支持的其他非阻塞通讯方式如某些型号支持的“消息队列”或“事件驱动”接口但这超出了基础Socket的范畴。6. 进阶应用从通讯到集成当基础的TCP通讯稳定后可以探索更高级的应用让机器人的集成能力再上一个台阶。6.1 与上位机软件深度集成机器人不仅可以发送简单字符串还可以遵循更复杂的协议与上位机如C#/WinForm、LabVIEW、Ignition等开发的SCADA/HMI软件交互。JSON格式将数据组织成JSON字符串发送如{robot_id: 1, position: [100,200,300], status: idle}。上位机用现成的JSON库解析非常方便进行结构化数据处理和显示。WebSocket对于需要双向、全双工、低延迟通讯的实时监控场景如数字孪生WebSocket是比HTTP轮询更优的选择。虽然Nachi原生可能不支持但可以通过在机器人同一网络下的网关工控机运行Node.js、Python服务做协议转换来实现。6.2 实现简单的Modbus TCP客户端Modbus TCP是工业领域事实上的标准协议。虽然Nachi没有原生指令但我们可以用Socket手动组包。 一个Modbus TCP请求报文包含事务标识符、协议标识符、长度、单元标识符、功能码、数据地址、数据。 例如读取保持寄存器功能码03的请求[00 01][00 00][00 06][01][03][00 6B][00 03]事务ID, 协议ID, 长度, 从站地址, 功能码, 起始地址, 寄存器数量 机器人程序需要按照这个格式用字节操作拼接出这个报文数组通过SOCKET_SEND发送。收到响应后再按Modbus格式解析。这需要你对Modbus协议和字节序有清晰的理解。6.3 状态监控与数据采集TCP通讯不仅是发送指令也是实现机器人状态监控和数据采集的绝佳通道。你可以创建一个定时任务周期性地将机器人的以下信息打包发送到服务器关节角度、笛卡尔坐标当前程序行号、运行状态运行、暂停、报警IO状态电机电流、温度等诊断信息 这些数据可以存入数据库用于生产报表、设备健康度预测预测性维护、以及大数据分析。从让机器人简单地“说一句话”到让它成为整个智能工厂数据流中的一个活跃节点稳定可靠的TCP通讯是实现这一切的血管。它没有视觉或力控那么“炫酷”但却是工业自动化系统稳定、高效运行的无声基石。每一次数据的成功发送与接收都是产线智能向前迈进的一小步。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进