简介:面向C#与ABB机器人二次开发场景的实战项目源码包,适合已具备C#基础、希望掌握工业机器人通讯与控制的学习者。内容围绕ABB Robot Studio SDK、RCI接口、RPL指令收发、TCP/IP连接认证、状态监控与异常处理展开,并以六轴工业机器人气囊抛光通讯与控制系统为主线,呈现从初始化、运行循环到关闭连接的程序结构。压缩包共61个文件,约1.11MB,包含13个cs源码、6个exe与6个dll可执行及依赖库、5个config配置、若干resx/resources资源文件和sln/csproj工程文件,便于直接打开解决方案梳理模块。已有6329人学习,可作为理解ABB二次开发流程、参考项目架构和排错思路的案例。
1. C# 上位机对接 ABB 控制器:先想清楚你要的是数据还是节拍
凌晨两点还在产线上盯机器人,上位机日志一堆连接超时,示教器那头 RAPID 跑得好好的,做 C# 与 ABB 通讯的人大多遇到过这种局面。问题常常不在代码多复杂,而在通道选错:只读产量数据,上 PC SDK 是杀鸡用牛刀;要做毫秒级位置引导,Socket 又扛不住。这套资源把 ABB 二次开发最常用的三条路线——PC SDK、Robot Web Services、RAPID Socket——的 C# 示例和 RAPID 配套程序收在一起,覆盖控制器发现、登录、变量读写、IO 和实时通道。适合做产线上位机、数据采集和工艺二次开发的人,也适合刚接手机器人集成、被「连不上控制器」卡过一整天的工程师。
2. 通讯方案选型:PC SDK、RWS、Socket 三条路的能力边界与延迟账
做 ABB 二次开发,第一个要回答的问题不是「C# 怎么写」,而是「走哪条通道」。三条主路线脾气完全不同,选错了后面全是补丁,改到怀疑人生。
2.1 PC SDK 是强类型重装备,不是万能钥匙
PC SDK 是 ABB 给 .NET 开发者的一套控制器访问库,ABB.Robotics.Controllers命名空间下把控制器、RAPID 任务、IO 系统、事件都封成了对象。用它发现控制器、登录、读写 RAPID 变量、订阅执行状态,代码写起来最像正常 C#。优点是强类型、IDE 有提示、异常信息相对清楚,做上位机集成时调试成本低。
但它的边界也很硬。第一,只支持 .NET Framework,官方没给 .NET Core / .NET 5+ 的版本,上位机如果是新框架写的,要么另起一个 .NET Framework 进程做桥,要么换通道。第二,部署要带一串 DLL,目标机没装对应运行时就直接起不来。第三,版本敏感,PC SDK 的版本要跟 RobotStudio、控制器 RobotWare 对得上,跨版本调用偶尔会撞到方法签名变化。
延迟上,PC SDK 一次变量读写在本机网络里大概几毫秒到十几毫秒,做产线状态采集、参数下发够用,做 4ms 级的位置闭环不够。它适合的是「上位机要频繁和控制器交换结构化数据」的场景,比如配方下发、报警采集、程序号切换。事件订阅是它相对另两条路的独特优势,ExecutionStatusChanged、OperatingModeChanged这类回调能省掉轮询,但回调里别做耗时操作,否则会堵 SDK 的内部线程。
2.2 RWS 是 HTTP 门面,跨平台但别指望实时
Robot Web Services 是控制器内置的 REST 接口,走 HTTP,返回 JSON。C# 端不需要任何 ABB 的 DLL,HttpClient 就能干活,.NET Framework、.NET 6、甚至跑在 Linux 上的服务都能调。接口覆盖 RAPID 符号读写、IO 信号读写、执行状态控制、事件日志,MES 层做数据采集基本够用。
代价是 HTTP 的开销。一次请求从建立连接到拿到响应,局域网里通常 10ms 起步,加上 JSON 序列化,20-100ms 是常态。这个量级做设备状态上报没问题,做节拍同步就会拖后腿。另一个门槛是权限:RWS 的用户是控制器 UAS 里的账号,要在用户管理里给远程访问权限,密码策略变了之后老脚本 401 是家常便饭。
RWS 还有一个容易被忽略的点:写 RAPID 变量同样要 Mastership,不是拿到账号就能直接改。很多人卡在这里,读接口调通了,写接口一直 403,以为是权限没给够,其实是没走/rw/mastership/request。这个接口在文档里不显眼,但少了它写操作全废。
2.3 Socket 最灵活,也最考验协议设计
Socket 路线是 RAPID 端用SocketCreate/SocketConnect/SocketSend/SocketReceive建 TCP 连接,C# 端用TcpClient或TcpListener对接。控制器不需要额外选项,只要网络通、RAPID 程序里写好收发逻辑就能跑。延迟可以压到个位数毫秒,适合节拍信号、工位握手、实时指令下发。
代价是「什么都没有」:没有消息边界、没有重连、没有心跳、没有序列化。TCP 是字节流,发两包可能粘成一包,发一包可能分两次到,这些都要在 C# 端自己处理。RAPID 的 Socket 指令也比较原始,字符串收发有长度限制,二进制要用\RawData,没有现成的 JSON 解析,协议得自己定。
我的经验是:只要涉及「机器人等上位机信号才能继续动作」,Socket 是首选;只要涉及「上位机想看机器人现在什么状态」,RWS 更省事;只有需要强类型对象模型和事件订阅时,才值得上 PC SDK。
2.4 一张表把选型钉死
| 维度 | PC SDK | RWS | Socket |
|---|---|---|---|
| 依赖 | ABB DLL + .NET Framework | HTTP + JSON | TCP,无额外依赖 |
| 典型延迟 | 5-20ms | 20-100ms | 1-10ms |
| C# 开发量 | 中 | 低 | 高 |
| 跨平台 | 否 | 是 | 是 |
| 控制器选项 | PC Interface | 远程访问权限 | 无 |
| 适合场景 | 上位机集成、事件订阅 | 数据采集、MES | 节拍同步、实时指令 |
表格里延迟是经验值,实际跟控制器型号、网络质量、消息大小都有关系。别拿它当性能承诺,拿它当排除法:需求落在哪个量级,就选哪条路。
2.5 控制器侧要先确认的三个开关
选完路线,先去示教器把开关确认了,不然后面代码写得再对也连不上。
PC SDK 需要控制器有 PC Interface 选项(616-1),没有这个选项,NetworkScanner 能扫到广播包但 TCP 连接会被拒。RWS 需要 UAS 用户有远程访问权限,部分版本还要在控制器配置里放开 Web 服务。Socket 本身不需要选项,但 RAPID 程序要占一个端口,端口号别跟控制器已用的服务撞。
网络层面,PC SDK 的发现走 UDP 广播,跨网段发现不到,要么把上位机放到同一网段,要么在代码里手动指定 IP。RWS 走 80/443,确认没被防火墙拦。Socket 走自定义端口,产线交换机如果有端口白名单,提前报备。
提示:先在示教器上用「备份/恢复」确认控制器版本和已购选项,再决定走哪条路。选项不对,换通道比改代码快。
3. PC SDK 落地:从 DLL 引用到第一个能读变量的连接
3.1 环境:RobotStudio 装好,项目框架别选错
PC SDK 不是 NuGet 上一个包就能搞定的东西,它跟着 RobotStudio 一起装。装完 RobotStudio,安装目录下会有 SDK 文件夹,里面是ABB.Robotics.Controllers.dll、ABB.Robotics.dll这些程序集。新项目里手动引用,或者把路径加到项目引用里。
框架选 .NET Framework 4.7.2 或 4.8,别选 .NET 6/7/8。PC SDK 的程序集是 .NET Framework 编译的,新框架下引用会报兼容性错误,硬调也可能在运行时炸。上位机如果是新框架,常见做法是单独起一个 .NET Framework 的控制台进程做通讯桥,用命名管道或本地 Socket 跟主程序交换数据。
控制器侧要确认 PC Interface 选项已开,并且控制器和上位机在同一网段,或者路由可达。
// 项目文件里确认目标框架 // <TargetFramework>net472</TargetFramework> using ABB.Robotics.Controllers; using ABB.Robotics.Controllers.Discovery; using ABB.Robotics.Controllers.RapidDomain;逻辑说明:三行 using 分别对应控制器对象、发现器、RAPID 数据类型。目标框架写在注释里,新建项目时在项目属性里选 .NET Framework 4.7.2。这段没有运行时逻辑,但框架选错后面全白搭。
3.2 发现控制器:广播扫不到就手动指定 IP
NetworkScanner 走 UDP 广播,调用Scan()后等几秒,Controllers 集合里就是同一网段能响应的控制器。每个 ControllerInfo 带 IP、系统名、RobotWare 版本、控制器状态。
var scanner = new NetworkScanner(); scanner.Scan(); foreach (ControllerInfo info in scanner.Controllers) { Console.WriteLine($"IP={info.IPAddress} System={info.SystemName} " + $"Version={info.Version} State={info.ControllerState}"); }逻辑说明:Scan()是阻塞的,内部等广播响应,网络里控制器多的时候要几秒。ControllerInfo 只读,拿来做展示和筛选。参数上,如果控制器不在同一网段,Controllers 会是空集合,这时候别怀疑代码,先 ping 一下,再考虑手动指定 IP。
手动指定 IP 的做法是跳过 Scanner,直接new Controller(IPAddress.Parse("192.168.1.10")),但这个重载在部分版本里行为不一致,稳妥做法还是先扫再按 IP 过滤,拿到 ControllerInfo 再构造 Controller。
3.3 登录与 Mastership:写操作的必要门槛
拿到 ControllerInfo 后构造 Controller,调Logon登录。默认用户是UserInfo.DefaultUser,匿名级别,读多数数据够用,写操作会被拒。要写就得请求 Mastership,相当于跟示教器抢控制权。
using (var ctrl = new Controller(info)) { ctrl.Logon(UserInfo.DefaultUser); Console.WriteLine($"Mode={ctrl.OperatingMode} State={ctrl.State}"); using (Mastership.Request(ctrl.Rapid)) { var rd = ctrl.Rapid.GetRapidData("T_ROB1", "MainModule", "nCount"); if (rd.Value is Num num) { Console.WriteLine($"before={num.Value}"); } rd.Value = new Num(42); } }逻辑说明:Controller 实现了 IDisposable,用 using 保证断开。Logon 之后才能访问 Rapid 和 IOSystem。Mastership.Request返回一个可释放对象,离开 using 块自动释放 Mastership,不释放的话示教器会一直显示远程占用。GetRapidData三个参数分别是任务名、模块名、变量名,变量必须是 VAR 或 PERS 类型,常量读得到写不了。
参数说明:Num 是ABB.Robotics.Controllers.RapidDomain下的数值类型,构造函数接收 double。写之前最好判断当前值,避免无意义写入触发控制器日志。如果变量是数组或结构体,要用 RapidData.Value 的复合类型,别直接强转。
3.4 读 IO 与订阅状态变化
IO 读写走 IOSystem,信号名要和控制器里配置的一致。写 IO 同样需要 Mastership,读不需要。
var di = ctrl.IOSystem.GetSignal("DI_Start"); Console.WriteLine($"DI_Start={di.Value}"); using (Mastership.Request(ctrl.Rapid)) { var doSignal = ctrl.IOSystem.GetSignal("DO_Busy"); doSignal.Value = 1; }逻辑说明:GetSignal按名字取信号,名字错了会抛异常而不是返回 null,所以调用前最好先列一遍ctrl.IOSystem.GetSignals()确认。写 IO 的值是 0/1,模拟量信号要用 AnalogSignal 类型,别拿 DigitalSignal 硬套。
事件订阅适合做状态监控,比如 ExecutionStatusChanged、OperatingModeChanged,回调里别做耗时操作,否则会阻塞 SDK 的内部线程。要更新界面就丢到 UI 线程的队列里,别在回调里直接 Invoke。
注意:Mastership 是独占的,示教器在手动模式下、或者有人在程序编辑器里操作时,Request 可能等不到。生产环境里请求要加超时和重试,别让上位机卡死。
3.5 部署时要带哪些文件
PC SDK 程序发布后,目标机要么装 RobotStudio(带运行时),要么把 SDK 的 DLL 一起拷过去并注册。常见翻车是开发机跑得好好的,拷到产线工控机上报Unable to load DLL或Could not load file or assembly。解决思路是把ABB.Robotics.Controllers.dll及其依赖(ABB.Robotics.dll、序列化程序集等)一起放进输出目录,确认目标机 .NET Framework 版本不低于项目目标版本。
还有个隐蔽的坑:目标机装过旧版 RobotStudio,GAC 里有旧版 SDK 程序集,运行时可能加载到旧版本而不是你输出目录里的新版本。排查时看异常的 Assembly 版本号,对不上就清理 GAC 或者改绑定重定向。
4. RWS 与 Socket 双通道:HTTP 控变量、TCP 走实时
4.1 RWS 的认证与请求骨架
RWS 走 HTTP Basic Auth,第一次请求带用户名密码,控制器返回会话 cookie。C# 里最省事的做法是 HttpClientHandler 挂 NetworkCredential,后续请求自动带认证。
var handler = new HttpClientHandler { Credentials = new NetworkCredential("Admin", "your-password"), PreAuthenticate = true }; var client = new HttpClient(handler) { BaseAddress = new Uri("http://192.168.1.10"), Timeout = TimeSpan.FromSeconds(5) };逻辑说明:PreAuthenticate 让第一次请求就带 Authorization 头,省一次 401 往返。Timeout 必须设,控制器忙的时候不设超时会挂住整个采集线程。密码里有特殊字符不用手动转义,NetworkCredential 会处理。
BaseAddress 只写到主机和端口,后面拼路径时注意别多写斜杠。控制器如果开了 HTTPS,地址换成https://,自签证书要在 Handler 里加证书回调,否则握手失败。
4.2 读变量、写变量、控执行
RWS 的 RAPID 符号接口路径是/rw/rapid/symbols。读单个符号要带 task 参数,返回 JSON 里_embedded._state[0].value是值。
// 读变量 var json = await client.GetStringAsync("/rw/rapid/symbols/nCount?task=T_ROB1"); using var doc = JsonDocument.Parse(json); var value = doc.RootElement .GetProperty("_embedded") .GetProperty("_state")[0] <p> <a href="https://download.csdn.net/download/theadore2017/10921266" style="color:#ec7500;font-size:14px;"> 本文还有配套的精品资源,点击获取 </a> <img alt="menu-r.4af5f7ec.gif" src="https://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif" style="width:16px;margin-left:4px;vertical-align:text-bottom;cursor:text;"> </p>