4. URCap与UR控制器通信

URCap运行在UR控制器的PolyScope环境中,本质上是一个Java后台服务加前端界面的组合。要让URCap真正“活”起来——读取机器人关节角度、发送运动指令、获取或设置I/O状态——就必须与UR控制器内部服务建立通信。UR官方为开发者提供了三条主要通道:XML-RPC、TCP/IP套接字和Modbus。它们不是互相替代的关系,而是各自覆盖不同的数据语义和实时性需求。理解三者的边界,比记住API调用更重要。

三条通道的定位差异

XML-RPC是UR控制器对外暴露的“标准远程调用接口”,默认监听端口40405(URCap后台也可通过Dashboard端口29999交互)。它把机器人状态、程序控制、I/O读写封装成结构化方法,例如get_actual_joint_positions()、get_digital_in(0)、set_digital_out(1, True)。优点是语义清晰、返回结构化数据、无需自己解析字节流;缺点是每次调用都有HTTP+XML封装开销,不适合高频循环。

TCP/IP套接字(UR通常开放30001~30003端口)提供的是实时数据流。30003端口以125Hz频率推送机器人状态包,包含关节位置、TCP位姿、关节电流、数字/模拟输入等字段,是二进制大端格式。它适合需要连续监控的场景,比如实时绘制轨迹或做安全监控,但需要开发者自己按字节偏移解析。

Modbus TCP则面向工业现场设备互联。UR控制器可作为Modbus从站(默认端口502),URCap通过读写寄存器来交换I/O和标志位。它的优势是与PLC、传感器、远程I/O模块天然兼容,适合把URCap接入更大的产线控制系统。

URCap 与 UR 控制器通信通道对照 URCap Java 后台服务 + PolyScope 界面 运行于控制器内 localhost 通信 XML-RPC 端口 40405 / 29999 结构化方法调用 状态查询 · 程序控制 · I/O TCP/IP 套接字 端口 30001 / 30002 / 30003 125Hz 二进制状态流 实时监控 · 高频采样 Modbus TCP 端口 502(从站) 寄存器读写 PLC · 远程I/O · 产线集成 UR 控制器 RTDE / 内部服务 机器人状态 · 运动控制 I/O 硬件抽象层 关节 · TCP · 数字/模拟量 选型原则:结构化查询用 XML-RPC · 高频实时流用 TCP/IP · 产线设备互联用 Modbus TCP

XML-RPC:读取状态与发送指令的主力

在URCap中调用XML-RPC,通常使用Apache XML-RPC库。核心步骤是构造XmlRpcClient指向127.0.0.1的40405端口,然后以方法名和参数数组发起调用。例如读取当前关节角度:

XmlRpcClient client = new XmlRpcClient("http://127.0.0.1:40405");
Object result = client.execute("get_actual_joint_positions", new Vector());
// 返回 Double[] 六个关节弧度值

发送运动指令时,UR并不推荐URCap直接调用底层运动方法,而是通过set_waypoint或写入程序变量来影响正在运行的程序。更常见的做法是:URCap通过XML-RPC读取get_actual_tcp_pose()获取当前位姿,结合外部传感器计算偏移量,再通过set_digital_out触发预置的UR程序分支。这样既保证了安全,又实现了柔性控制。

读取I/O信号同样直接:get_digital_in(0)返回布尔值,get_analog_in(0)返回0~1之间的浮点数(对应0~10V或4~20mA量程)。写入则用set_digital_out和set_analog_out。需要注意的是,XML-RPC调用是同步阻塞的,单次往返通常在5~20ms,因此不要把它放在125Hz的控制循环里。

TCP/IP:解析125Hz状态流

当URCap需要连续监控机器人状态时,应连接30003端口。该端口以125Hz推送一个长度固定的二进制包(UR e-Series约为1108字节,具体随版本略有差异)。包内字段按大端序排列,关键偏移包括:

  • 偏移 0~3:包长度(int,大端)
  • 偏移 252~275:六个关节目标位置(double,弧度)
  • 偏移 444~467:六个关节实际位置(double,弧度)
  • 偏移 540~563:TCP 实际位姿(x,y,z,rx,ry,rz,double)
  • 偏移 720~731:数字输入位掩码(uint64)

解析时用DataInputStream配合ByteBuffer.order(ByteOrder.BIG_ENDIAN)逐字段读取。由于数据包持续到达,建议在独立线程中循环读取,并通过线程安全队列把最新状态传递给UI线程。这样URCap界面上的实时关节角度、TCP轨迹就能以接近实时的速度刷新,而不会阻塞PolyScope主线程。

Modbus TCP:接入产线设备

UR控制器内置Modbus从站服务,URCap可以作为Modbus主站(客户端)去读写寄存器。典型场景是:URCap需要读取产线上某台PLC的“允许启动”信号,或者把机器人当前状态写入PLC的寄存器供上位机显示。

使用ModbusTCPMaster类连接127.0.0.1:502,然后调用readDigitalInputs(0, 8)读取8个数字输入,或writeMultipleRegisters(0, values)写入保持寄存器。UR的Modbus地址映射与I/O配置相关:数字输入对应地址0~127,数字输出对应128~255,模拟输入对应256~383,模拟输出对应384~511。实际地址需在UR的“安装→现场总线→Modbus”中确认。

Modbus寄存器是16位无符号整数。如果要传输浮点数(如TCP坐标),需要把double拆成两个寄存器,并约定字节序。URCap与PLC双方必须使用相同的拆分规则,否则会出现“数值看起来完全不对”的典型问题。

三种方式的协同使用

实际项目中,三者往往同时存在。一个典型的URCap可能这样分工:用XML-RPC在初始化时读取机器人型号和软件版本;用TCP/IP 30003端口持续刷新界面上的关节角度曲线;用Modbus TCP与产线PLC交换“请求抓取”“抓取完成”等握手信号。这样既避免了XML-RPC高频调用的开销,又获得了实时数据流,同时保持了与工业设备的兼容性。

无论使用哪种通道,URCap都不应绕过UR的安全配置直接控制关节。运动指令必须通过UR程序或URCap的“程序节点”机制下发,确保安全限位、速度限制和急停逻辑仍然生效。直接向底层服务写入关节目标值属于危险操作,仅应在仿真或受控测试环境中验证。

调试与验证要点

验证XML-RPC是否连通,可以在URCap日志中打印get_actual_joint_positions()的返回值,正常应得到6个约在-π~π之间的弧度值。验证TCP/IP流,可以统计每秒收到的包数量,正常应接近125;如果明显偏低,检查是否在读取循环中做了耗时操作。验证Modbus,可以先用Modbus Poll等工具连接502端口,确认寄存器映射与UR配置一致,再在URCap中实现读写。

通信异常时,优先检查端口是否被占用、UR软件版本是否匹配、防火墙是否拦截localhost连接。URCap运行在控制器内部,通常不受外部防火墙影响,但若通过URSim仿真,则需确认仿真器的端口映射是否正确。