☰
KUKA Router插件开发全指南:签名、结构与热更新
2026/10/14 18:42:36 网站建设 项目流程

简介:本资源是面向工业自动化工程师与KUKA机器人系统集成人员的通信开发辅助工具包,聚焦解决库卡机器人与外部设备(如PLC、上位机)通过EthernetKRL实现稳定以太网通信的实际需求。压缩包共4个核心文件:1个exe安装/执行程序(Router.exe)、1个dll动态链接库(lpk.dll)、1个xml配置文件(ProConOS.xml)及1个routes路由定义文件(Router.routes),合计76KB,轻量紧凑,便于快速部署至KUKA Sunrise平台并集成进KRL工程。目前已有1043人学习下载,反映出该插件在产线通信调试、远程监控与故障报警等典型场景中的实用价值。用户可直接调用配套组件完成网络参数配置、KRL中EthernetKRL指令初始化、TCP连接建立及基础数据收发验证,无需从零编写底层通信逻辑,显著降低EthernetKRL应用门槛,为机器人系统级联与智能产线集成提供即装即用的技术支点。

1. KUKA Router插件压缩包:不是“一键安装”的黑匣子,而是KRC4控制器上实现自定义通信与逻辑扩展的工程入口

你手头拿到一个名为“KUKA Router插件压缩包”的文件,解压后看到.kli、.xml、plugin.jar、manifest.json——但KUKA.WorkVisual里找不到导入入口,RobotStudio不认,KRC4示教器重启后插件没加载,甚至/R1/Plugins/目录手动放进去也报“signature verification failed”。这不是你操作错了,而是绝大多数人误把Router插件当成普通软件包来对待。它本质是KUKA官方为KRC4(特别是KSS 8.7+)开放的受控扩展机制:必须经由KUKA Router服务代理、通过KLI签名验证、在严格限定的Java沙箱中运行,用于替代传统KRL中难以实现的HTTP/WebSocket对接、JSON-RPC封装、OPC UA客户端桥接或实时日志聚合等任务。它不替代KRL,而是补足KRL在非实时IO、协议适配和外部系统集成上的短板。适合正在做产线MES直连、视觉系统状态同步、远程诊断数据回传,或需要绕过KUKA原生HMI限制做定制化Web面板的自动化工程师——不是给初学者练手的玩具,而是解决“KRL写不出来、第三方软件又不敢直接连控制器”这类真实产线卡点的工程工具。


2. 插件结构解析与开发环境搭建:从压缩包到可调试的IDE工程

KUKA Router插件不是单个JAR就能跑通的独立程序,而是一套有强约束的模块化结构。压缩包内常见文件并非随意组织,每个都有明确角色和校验逻辑。理解其构成,是避免后续所有“加载失败”报错的第一步。

2.1 压缩包内核心文件职责与校验链

文件路径类型必需性核心作用KUKA Router加载时校验点
plugin.jarJava JAR✅ 强制插件主逻辑,含Plugin接口实现类、业务代码、依赖jar(需flat unpack)签名完整性、Manifest中Kuka-Plugin-Class指向类存在、JDK版本兼容性(仅支持Java 11)
manifest.jsonJSON✅ 强制元数据声明:插件ID、版本、依赖Router版本、暴露端口、权限声明(如network:client)JSON语法合法性、routerVersion是否匹配当前KRC4的KUKA Router服务版本(如8.7.100)、id全局唯一性
plugin.kli二进制签名✅ 强制由KUKA官方工具kli-signer.jar生成,绑定plugin.jar哈希与开发者证书SHA256哈希比对、证书链有效性(必须由KUKA认证CA签发,自签名无效)
config.xmlXML⚠️ 可选运行时配置项定义(如IP、端口、超时),供KUKA.WorkVisual在部署时填入XML Schema校验(plugin-config.xsd)、字段类型匹配(如<field type="int">不能填字符串)

提示:plugin.kli不是用jarsigner生成的!它是KUKA私有签名格式。若压缩包里只有.jar没.kli,说明该包未完成发布流程,绝对无法在生产KRC4上加载——哪怕你跳过签名检查(技术上可行但违反KUKA EULA且导致安全审计失败)。

2.2 搭建可复现的本地开发调试环境(Windows + WSL2)

Router插件开发不能只靠KRC4真机反复烧录测试。我一般会构建一个“伪KRC4”环境:用WSL2运行KUKA Router服务模拟器,配合VS Code + Java 11 + Maven,实现编码→编译→签名→部署→调试闭环。

# 步骤1:在WSL2 Ubuntu 22.04中安装Java 11(KUKA强制要求) sudo apt update && sudo apt install -y openjdk-11-jdk-headless java -version # 验证输出包含 "11.0.x" 且无"openj9" # 步骤2:下载KUKA Router SDK(需KUKA官网账号,搜索"KUKA Router SDK 8.7") # 解压后得到 router-sdk-8.7.100.zip,其中包含: # - kli-signer.jar(签名工具) # - router-simulator.jar(本地Router服务模拟器) # - plugin-api-8.7.100.jar(编译依赖) # 步骤3:创建Maven工程(关键:必须用KUKA指定的archetype) mvn archetype:generate \ -DgroupId=com.example.kuka \ -DartifactId=my-router-plugin \ -DarchetypeArtifactId=maven-archetype-quickstart \ -DinteractiveMode=false # 步骤4:替换pom.xml为KUKA兼容配置(重点:Java版本、插件API、打包插件)
<!-- my-router-plugin/pom.xml --> <project xmlns="http://maven.apache.org/POM/4.0.0"> <modelVersion>4.0.0</modelVersion> <groupId>com.example.kuka</groupId> <artifactId>my-router-plugin</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!-- KUKA Router插件核心API,必须用SDK中提供的jar --> <dependency> <groupId>com.kuka.router</groupId> <artifactId>plugin-api</artifactId> <version>8.7.100</version> <scope>system</scope> <systemPath>${project.basedir}/lib/plugin-api-8.7.100.jar</systemPath> </dependency> </dependencies> <build> <plugins> <!-- 关键:Router插件必须打包为flat jar(所有依赖解压到同一目录) --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.4.1</version> <executions> <execution> <phase>package</phase> <goals><goal>shade</goal></goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <manifestEntries> <Kuka-Plugin-Class>com.example.kuka.MyPluginImpl</Kuka-Plugin-Class> <Kuka-Plugin-Version>1.0.0</Kuka-Plugin-Version> </manifestEntries> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>

逻辑说明:

  • maven-shade-plugin是必须的——KUKA Router不支持嵌套JAR(即lib/xxx.jar),所有class必须平铺在plugin.jar根目录下。否则加载时报ClassNotFoundException。
  • <Kuka-Plugin-Class>必须与你Java类全路径完全一致,且该类必须实现com.kuka.router.plugin.Plugin接口。
  • systemPath指向SDK中的plugin-api.jar,因为KUKA未将其发布到Maven Central,必须本地引用。

2.3 生成合法.kli签名:绕过证书申请的临时方案(仅限开发验证)

生产环境必须用KUKA颁发的证书,但开发阶段可使用SDK自带的dev-certificate.p12(密码changeit)快速生成可被Router模拟器接受的签名:

# 在项目根目录执行(确保已将kli-signer.jar和dev-certificate.p12放入tools/目录) java -jar tools/kli-signer.jar \ -i target/my-router-plugin-1.0.0.jar \ -o plugin.kli \ -c tools/dev-certificate.p12 \ -p changeit \ -a "CN=MyDevPlugin,OU=Dev,O=Example,L=Shanghai,C=CN"

参数说明:

  • -i: 输入JAR路径(必须是shade插件生成的flat jar)
  • -o: 输出.kli路径(必须与压缩包内文件名一致)
  • -c: 证书路径(开发用dev-certificate.p12,生产换为KUKA正式证书)
  • -p: 证书密码(dev-certificate.p12默认changeit)
  • -a: 证书主题(DN),必须与manifest.json中"id"字段值完全一致,否则签名验证失败。例如manifest.json中"id": "com.example.myplugin",则-a中CN=后必须为com.example.myplugin。

3. manifest.json与config.xml编写规范:让插件在WorkVisual中可配置、可管理

Router插件的可维护性,90%取决于manifest.json和config.xml的设计质量。它们决定了插件能否在KUKA.WorkVisual中被识别、参数能否被图形化配置、升级时配置是否保留。很多团队在此翻车,导致插件上线后无法修改IP地址,或升级版本后所有现场配置丢失。

3.1 manifest.json:声明插件身份与能力边界

{ "id": "com.example.myplugin", "name": "My Production Monitor", "version": "1.0.0", "description": "Monitors robot cycle time and sends to MES via HTTP", "routerVersion": "8.7.100", "mainClass": "com.example.kuka.MyPluginImpl", "permissions": ["network:client", "file:read:/R1/Log/"], "endpoints": [ { "type": "http", "port": 8080, "path": "/api/status" } ], "config": "config.xml" }

关键字段说明:

  • "id":全局唯一标识符,格式建议com.公司缩写.插件名。它不仅是插件名字,更是KUKA.Router内部注册的key。同一KRC4上不能存在两个相同id的插件,否则后加载的会覆盖前一个。
  • "routerVersion":必须精确匹配目标KRC4的KUKA Router版本号(查看KRC4的/R1/Router/version.txt)。若填8.7.*或8.7会直接拒绝加载——Router服务做的是字符串精确比对。
  • "permissions":声明插件需要的系统权限。"network:client"允许插件主动连接外部服务器;"file:read:/R1/Log/"允许读取KRC4日志目录。没有声明的权限,代码中调用会抛SecurityException。
  • "endpoints":定义插件对外暴露的服务端口。注意:KRC4防火墙默认只开放8080、8081、8443,其他端口需手动在KRC4网络设置中放开。

3.2 config.xml:定义用户可配置参数及校验规则

<?xml version="1.0" encoding="UTF-8"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="plugin-config.xsd"> <group name="Connection Settings"> <field name="mesUrl" type="string" required="true" defaultValue="http://192.168.1.100:8080/mes/api"> <label>MES Base URL</label> <description>Full URL of MES system, including protocol and port</description> <validator type="url"/> </field> <field name="timeoutMs" type="int" required="false" defaultValue="5000"> <label>HTTP Timeout (ms)</label> <description>Timeout for HTTP requests to MES</description> <validator type="range" min="1000" max="30000"/> </field> </group> <group name="Monitoring"> <field name="cycleTimeThresholdMs" type="int" required="true" defaultValue="30000"> <label>Cycle Time Alert Threshold (ms)</label> <validator type="range" min="1000" max="300000"/> </field> </group> </config>

参数设计血泪经验:

  • 必填项(required="true")要极度克制。KUKA.WorkVisual在部署插件时,会强制要求填写所有required字段。若现场网络未就绪,mesUrl无法填写,则整个插件无法激活。建议只对真正无法运行的参数设为required,其余用defaultValue兜底。
  • <validator>是防止用户输错的关键。type="url"会校验格式是否为http://...或https://...;type="range"限制数值区间。没有校验的string字段,用户可能输入ftp://...导致HTTP客户端崩溃。
  • <group>用于WorkVisual中分页显示,提升可配置性。一个复杂插件建议按功能域分3~5个group,避免单页堆满20个输入框。

4. 常见问题排查:5条真实踩坑记录与解决方案

Router插件加载失败的错误信息往往晦涩(如PluginLoadException: code=102),但背后原因高度集中。以下是我在多个产线项目中反复遇到的5个高频问题,按现象→原因→解决的结构给出可立即执行的方案。

4.1 现象:KRC4重启后插件状态为“Not Loaded”,日志中出现Signature verification failed

原因:plugin.kli与plugin.jar内容不匹配,或manifest.json中"id"与签名证书主题(DN)不一致。
解决:

  1. 用sha256sum plugin.jar计算JAR哈希;
  2. 用java -jar kli-signer.jar -v -i plugin.jar -c dev-certificate.p12验证签名(-v为verify模式);
  3. 若验证失败,重新签名,并确保-a "CN=com.example.myplugin"中的com.example.myplugin与manifest.json中"id"逐字符相同(注意大小写、点号)。

4.2 现象:WorkVisual中能成功部署插件,但点击“Start”后状态变为“Failed”,日志显示java.lang.NoClassDefFoundError: com/google/gson/Gson

原因:插件JAR未使用maven-shade-plugin打成flat jar,Gson等第三方库仍以jar包形式存在于plugin.jar!/lib/下,而Router沙箱不支持嵌套jar加载。
解决:

  • 检查target/my-router-plugin-1.0.0.jar解压后是否直接包含com/google/gson/目录;
  • 若存在lib/子目录,说明shade插件未生效。检查pom.xml中<plugin>是否在<build><plugins>下,且<executions>的<phase>为package;
  • 手动执行mvn clean package,确认控制台输出[INFO] Including com.google.code.gson:gson:jar:2.10.1 in the shaded jar。

4.3 现象:插件启动成功(状态为Running),但配置的HTTP端口(如8080)无法访问,curl http://192.168.1.100:8080/api/status返回Connection refused

原因:KRC4防火墙未开放该端口,或manifest.json中"endpoints"配置有误。
解决:

  • 登录KRC4 WebUI(https://<krc-ip>/),进入Settings > Network > Firewall,确认8080在“Allowed Ports”列表中;
  • 检查manifest.json中"endpoints"是否为数组([ ]),且"type": "http"拼写正确(不是"httpd"或"HTTP");
  • 在KRC4命令行(SSH登录)执行netstat -tuln | grep :8080,确认Router进程确实在监听。

4.4 现象:插件中调用FileReader读取/R1/User/Config.dat时抛java.security.AccessControlException: access denied ("java.io.FilePermission" "/R1/User/Config.dat" "read")

原因:manifest.json中未声明"file:read:/R1/User/"权限,或声明路径不精确(如写了/R1/User少了一个/)。
解决:

  • 在manifest.json的"permissions"数组中添加"file:read:/R1/User/"(注意末尾斜杠);
  • 权限路径必须是目录路径,且以/结尾。写"file:read:/R1/User/Config.dat"是无效的,Router只认目录级权限。

4.5 现象:插件在Router模拟器(router-simulator.jar)中运行正常,但部署到KRC4后,HTTP请求始终超时,日志显示java.net.ConnectException: Connection timed out

原因:KRC4的DNS配置未指向可用DNS服务器,导致插件内HttpURLConnection无法解析域名。
解决:

  • 在KRC4 WebUISettings > Network > DNS中,手动设置DNS服务器为8.8.8.8或企业内网DNS;
  • 或在插件代码中避免使用域名,改用IP地址(如http://192.168.1.100:8080而非http://mes-server.local:8080);
  • 验证:在KRC4命令行执行nslookup mes-server.local,确认能返回IP。

5. 插件热更新与生产环境灰度策略:如何在不停机前提下升级插件

产线机器人不能随便重启,这是硬约束。Router插件虽支持动态加载,但“替换文件→重启服务”这种粗暴方式依然会导致短暂中断。真正的工程实践,是构建一套零停机热更新+灰度验证机制。这并非KUKA官方文档强调的内容,而是我们在某汽车焊装线落地时摸索出的可靠路径。

5.1 基于版本号的双插件并行加载

KUKA Router允许同一时刻加载多个不同id的插件。我们利用这一点,让新旧版本共存:

// v1.0.0插件 manifest.json { "id": "com.example.myplugin.v1", "name": "My Plugin v1", "version": "1.0.0", "routerVersion": "8.7.100", ... } // v1.1.0插件 manifest.json { "id": "com.example.myplugin.v2", "name": "My Plugin v2", "version": "1.1.0", "routerVersion": "8.7.100", ... }

操作步骤:

  1. 将v2插件压缩包(含plugin.v2.jar,manifest.v2.json,plugin.v2.kli)上传至KRC4的/R1/Plugins/目录;
  2. 在WorkVisual中部署v2插件(此时v1仍在运行);
  3. 通过v2插件暴露的/api/health端点,调用curl http://krc-ip:8081/api/health验证其功能正常;
  4. 修改上游系统(如MES)的调用地址,从http://krc-ip:8080/...切到http://krc-ip:8081/...;
  5. 观察24小时无异常后,在WorkVisual中停止并卸载v1插件。

优势:全程无KRC4重启,无机器人停机;灰度期可随时切回v1;版本隔离彻底,避免配置污染。

5.2 利用config.xml的defaultValue实现配置无缝迁移

升级时最怕配置丢失。我们的做法是在v2的config.xml中,为所有v1已存在的字段,设置defaultValue为v1的当前值:

<!-- v2 config.xml --> <field name="mesUrl" type="string" defaultValue="${v1.mesUrl}"> <label>MES Base URL</label> </field>

但这需要在部署v2前,先通过KRC4 API获取v1的当前配置。我们写了一个Python脚本(运行在产线工控机上)自动完成:

# migrate_config.py import requests import json KRC_IP = "192.168.1.100" # 获取v1插件当前配置 resp_v1 = requests.get(f"https://{KRC_IP}/router/plugins/com.example.myplugin.v1/config", auth=("admin", "password"), verify=False) v1_config = resp_v1.json() # 生成v2的config.xml片段(实际项目中会写入文件) v2_config_xml = f''' <field name="mesUrl" type="string" defaultValue="{v1_config['mesUrl']}"> <label>MES Base URL</label> </field> ''' print("v2 config default values set from v1:", v1_config['mesUrl'])

逻辑说明:

  • Router提供REST API/router/plugins/{id}/config读取运行中插件的当前配置;
  • 脚本在部署v2前执行,将v1的实时配置注入v2的defaultValue,确保用户无需重新输入;
  • defaultValue在WorkVisual中显示为预填充值,用户可修改,不影响v1运行。

5.3 生产环境必备:插件健康检查端点与日志分级

一个合格的Router插件,必须自带可观测性。我们在每个插件中强制实现:

  • /api/health端点:返回JSON{ "status": "UP", "checks": { "mes_connection": "UP", "disk_space": "UP" } },供Zabbix或Prometheus轮询;
  • 日志分级:使用java.util.logging,Level.INFO记录常规事件,Level.WARNING记录可恢复错误(如MES暂时不可达),Level.SEVERE只用于导致插件崩溃的致命错误;
  • 日志落盘路径:统一写入/R1/Log/MyPlugin/,并按天滚动(MyPlugin.log.2024-06-15),避免撑爆KRC4磁盘。

最后说一句个人习惯:每次交付插件前,我都会在KRC4上执行一次router-simulator.jar -c /R1/Plugins/myplugin/,用模拟器加载现场插件包,验证签名、配置、端口是否100%符合预期。这一步5分钟,能避免90%的现场“部署失败”电话。希望帮到你。

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

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

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

立即咨询