pc 您所在的位置:网站首页 ABB机器人通信端口可以用着等待信号吗 pc

pc

2023-12-18 21:55| 来源: 网络整理| 查看: 265

Capi部分 PC SDK应用程序特定的配置数据应添加到部分。 ... PC SDK中实现了以下标记: 如果您经常连接的网络中存在控制器(机器人系统),则可能需要使用标记。 它具有一个id属性,其中包含用大括号括起来的字符串。 它是系统的全局唯一标识符(GUID),可以在机器人系统的INTERNAL文件夹中的system.guid文件中找到。 使用此机制,您可以使用默认构造函数为指定控制器创建Controller对象: VB: Dim aController As Controller = New Controller() C#: Controller aController = new Controller(); 扫描可用的控制器时,可以在本地网络外部添加控制器。 一种方法是在标记中添加这些控制器的IP地址:

通过使用标记,您可以选择使用Windows回发委托。 为了使这项工作有效,您还必须从Windows窗体实现对该事件的订阅,否则事件处理程序将不会接收该事件: 注意

使用此策略进行事件处理可能会影响应用程序的性能。 PC与控制器之间的通讯 COM技术 PC SDK使用基于COM技术的内部Controller API与控制器进行通信。 该API使用套接字和面向实际和虚拟控制器的本地TCP / IP堆栈(请参见定义)。

注意

您应该意识到,.NET垃圾收集器不会收集COM对象,但是这些对象需要由应用程序程序员明确地处理。 有关更多信息,请参阅访问控制器。 资源识别 使用基于对象的层次结构描述了所有控制器资源,包括真实资源和虚拟资源。 每个资源都是唯一标识的,包括有关使用哪个控制器拥有唯一的系统ID或IP地址的信息。

控制器是层次结构的顶部对象: “/and so on” 技巧: 包含这样的路径的错误消息指示在哪里寻找问题。 硬件实时需求 由于以下原因,PC CAPI无法满足严格的实时要求:

1.该API的一部分在非实时操作系统上执行。

2.通过网络使用TCP / IP进行通信

3.控制器有时会执行具有较高优先权的任务。

注意

实际控制器的最小响应时间应该在10到100毫秒左右。 许可证验证-仅适用于PC SDK 5.10之前的版本 概述 部署的PC应用程序在执行过程中会进行许可证验证,检查所有应用程序程序集是否已在具有有效PC SDK许可证密钥的PC上构建。 如果缺少密钥,则PC SDK中的某些功能将在执行期间引发异常。

注意

在5.10版本中删除了许可证验证。 因此,不再需要下一节中详细介绍的licx文件。 Licenses.licx 许可证密钥应放在“ Licenses.licx”文件中,该文件应作为嵌入式资源添加到您的项目中。 为了方便起见,PC SDK安装中包含以下文件:C:\ Program Files \ ABB Industrial IT \ Robotics IT \ SDK \ PC SDK5.xx。 VS 2005中PC SDK的关键是:

ABB.Robotics.Controllers.Licenses.PCSdk, ABB.Robotics.Controllers

注意

前面的路径适用于RAB 5.09和更早版本。 它不适用于新安装。     技巧

许可证编译器(Lc.exe)是.Net Framework工具。 它从.licx文件生成.license文件。 如果需要更多详细信息,请在MSDN(licx,lc.exe)中搜索 版本升级和兼容性 关于本节 本部分解决与不同版本的Robotware的兼容性问题。      注意

PC SDK 5.11至5.13支持Visual Studio 2008,而PC SDK 5.14支持Visual Studio 2010。 匹配的PC SDK和RobotWare版本 您应该知道,PC SDK是为特定的RobotWare版本开发和测试的。 因此,一般规则是您为特定版本开发应用程序。

但是,可以保证版本之间的兼容性(例如,RobotWare 5.11.01将与PC SDK 5.11兼容)。 RobotWare升级 在应用程序生存期内的某个时间,您的应用程序所针对的机器人系统可能会使用更高版本的RobotWare进行升级。

PC SDK通常与较新的RobotWare版本兼容。 但是,在客户方托管PC SDK应用程序的PC仍需要升级Robot Communication Runtime,以使其与新的robotware版本匹配。 有关更多信息,请参见ABB工业机器人通讯Runtime.msi。 如果决定升级PC SDK应用程序,则还必须记住要升级客户PC的运行时环境。 有关更多信息,请参见PC SDK应用程序的部署。

注意

您可以在发行说明中找到有关不同PC SDK版本之间兼容性的所有详细信息。      技巧

编译项目时,请注意任何过时方法的警告,因为这些警告可能会在下一个PC SDK版本中删除。 开发控制器应用程序 介绍 关于本节、 本章介绍PC SDK应用程序的分析,设计和实现。

它提供了以下特定的编程问题,这些问题对于PC SDK用户而言非常重要:

1.线程冲突以及如何避免它们

2.控制器事件和事件处理

3.错误和异常处理

4.用户授权系统

本章不包括有关如何设置第一个项目的动手信息,也不包括有关如何使用PC SDK类库的详细信息,因为这些主题将在专用章节中介绍。 基本方法 在大多数方面,与普通的.NET开发相比,使用PC SDK进行应用程序开发没有太大区别。 .NET类库用于不是机器人特定的所有内容。 另外,您使用SDK的公共Controller API。

在你开始之前

阅读本手册的所有相关部分,了解有关PC SDK编程的基础知识。 可以放心,这是一项节省时间的活动,不必急于编码。     开发期间

经常测试应用程序功能。 分析与设计 关于本节 PC SDK的目的是提供满足特定客户需求的操作员界面。 本节重点介绍实际编码之前的开发阶段:分析和设计。 面向对象的软件开发 .NET完全是面向对象的。 平台服务分为不同的名称空间,例如System.Collections,System.Data,System.IO,System.Security等。 每个名称空间包含一组相关的类,这些类允许访问平台服务。 PC SDK也是完全面向对象的。 它的类库在不同的命名空间中组织,例如ABB.Robotics.Controllers.RapidDomain,ABB.Robotics.Controllers.MotionDomain等

开始开发自定义应用程序时,您需要具有一些面向对象的经验。 假定您对诸如对象,类,方法,继承,封装等概念了解。 面向对象的分析与设计 面向对象的分析和设计(OOAD)是计算机科学文献中的一个热门话题,在此之前,普遍接受在开始编码之前进行全面分析和设计的重要性。 精心设计的OO应用程序在现实世界中具有真实的代表。 班级有明确定义的职责范围,并以有效的方式进行协作以达到要求。 基于沟通和用例的分析 正如已经指出的那样,PC SDK的主要思想是,可以在考虑最终用户的特定需求的情况下,使其更接近最终用户来开发自定义操作员界面。 因此,毋庸置疑,分析至关重要。

面向对象分析的结果是对我们要构建的内容的描述,通常表示为概念模型。 描述我们想要构建的内容所需的任何其他文档,例如用户界面图片,也是分析的一部分。

PC SDK开发最重要的方面是与最终用户的沟通。 强烈建议开展活动,以支持对应该开发的内容的共识。 这些活动可能包括:

一起创建和讨论用例

编码或绘制原型并获得最终用户反馈

简而言之,最好的策略是让早期阶段的最终用户参与进来,并使他们参与整个开发项目。 设计关于管理复杂性 面向对象设计的结果详细说明了如何使用对象构建系统。 抽象用于将复杂的问题分解为可管理的块。 这使得有可能从整体上理解问题或以较低的抽象水平研究问题的一部分。

成为熟练的面向对象设计师需要数年时间。 设计理论必须转化为实践经验,并一遍又一遍地反复进行。

目标是产生高质量的代码,该代码具有成本效益且易于维护。 例如,当添加新功能时,只需对现有代码进行最少的更改,而大多数更改将作为新方法和新类处理,就可以实现这一点。 如何设计 例如,在创建诸如.NET Framework之类的软件以及IRC5的自定义操作员视图时,复杂性存在巨大差异。 显然,系统越复杂,需要的设计就越仔细。 因此,自定义应用程序需要更大,更复杂,您更有可能在设计上花费时间。

下面在决定开始编码之前需要多好的设计应用程序之前提出了一些注意事项:

它要多少代码?   如果这将是一个仅具有一个视图和几个按钮的非常简单的应用程序,则无需在不同的类和文件之间拆分代码。

如果会有大量的代码,以后可能会有进一步的扩展,那么花时间在设计上就变得更加重要。   不同的开发人员会使用不同的类/组件吗? 您将自己维护代码,还是由他人维护?   如果可以,那么花时间在设计上就变得更加重要。   应用程序的实时方面重要吗?   如果是,则有效编码很重要。 如果您花一些时间在设计上,这将更容易实现。 复杂还是轻松 使用PC SDK可以在一两天内创建一个简单的自定义应用程序。 具有大量不同视图的大型定制应用程序具有高级机器人系统功能,但是可能要花费数月的开发时间,并且需要大量的编程技能。建议您开始开发一个简单的应用程序,然后在目标平台上执行该应用程序 继续进行高级PC SDK编程。 控制器事件和线程 概述 控制器事件是来自控制器的消息,表明发生了某些事情。 PC SDK应用程序可以捕获事件并采取措施。

控制器事件使用其自己的线程。 这意味着用户界面线程和控制器事件线程可能会发生冲突。 本节提供有关如何防止这种情况的信息。 控制器事件 PC SDK应用程序可以订阅许多控制器事件。 这些都在《参考手册PC SDK》中进行了描述。

下表显示了PC SDK中存在的一些事件。

StateChanged 控制器状态已更改。 OperatingModeChanged 控制器的操作模式已更改。 ExecutionStatusChanged 控制器执行状态已更改。 Changed I / O信号的值或状态已更改。 MessageWritten EventLog有新消息 ValueChanged RAPID数据的值已更改。 注意

不能保证在设置/激活控制器事件时会收到初始事件。 您需要从控制器读取初始状态。 GUI和控制器事件线程发生冲突 您应该意识到,控制器事件在PC平台上使用其自己的线程。如果GUI线程和控制器事件线程发生冲突,则可能会发生死锁或覆盖数据。当控制器事件由用户界面更新成功后可能会发生这种情况,这确实是非常常见的情况。

然后,您需要在代码中采取措施来控制用户界面更新是由GUI线程而不是由控制器事件线程执行的。这是通过使用Invoke或BeginInvoke方法强制执行线程切换来完成的。有关代码示例的更多信息,请参见Invoke方法。

另一方面,如果控制器事件不应引起用户界面的任何更新,则不应执行任何特殊操作。使用Invoke / BeginInvoke对性能要求很高,不应过多使用。

注意

线程冲突通常会导致绞死。然后,PC应用程序UI停止响应,必须重新启动该应用程序。

检查遇到这种情况时引发了什么异常。异常System.InvalidOperationException(PC平台)指示线程冲突。有关如何使用Invoke解决问题的信息,请参见下一部分。 Invoke 方法 所有PC应用程序窗口视图都必须继承Control / TpsControl,后者实现Invoke和BeginInvoke。 这些方法在拥有控件的基础窗口句柄的线程上执行指定的委托/事件处理程序,从而强制从工作线程切换到GUI线程。 这正是需要将控制器事件传达给系统最终用户时所需要的。

应该在事件处理程序内部调用调用,以处理控制器事件。 注意,您必须为发送者和参数对象创建一个新的对象数组: VB: Me.Invoke(New EventHandler(UpdateUI), New Object {Me, e}) C#: this.Invoke(new EventHandler(UpdateUI), new Object[] { this, e }); 还要注意,如果在Invoke方法中使用EventHandler而不是特定的委托类(例如DataValueChangedEventHandler),则需要在委托中键入参数以更新用户界面。 下例显示了如何完成此操作: VB: Private Sub UpdateUI(ByVal sender As Object, ByVal e As EventArgs) Dim args As StateChangedEventArgs args = DirectCast(e, StateChangedEventArgs) Me.label1.Text = args.NewState.ToString() End Sub C#: private void UpdateUI(object sender, EventArgs e) { StateChangedEventArgs args;args = (StateChangedEventArgs)e;this.label1.Text = args.NewState.ToString(); } 注意

Invoke和BeginInvoke之间的区别在于,前者进行同步调用并将挂起,直到GUI操作完成,而BeginInvoke异步执行指定的事件处理程序。 您要使用哪种方法取决于程序的逻辑。 建议尽可能选择BeginInvoke。    注意 如果您的代码尝试从后台线程访问GUI控件,则.NET公共语言运行时将抛出System.NotSupportedException(FlexPendant平台)或System.InvalidOperationException(PC平台)。 用户授权系统 概述 在机器人控制器中,有一个控制用户访问的系统:用户授权系统(UAS)。 如果使用此功能,则每个用户都需要用户名和密码才能通过RobotStudio登录到机器人控制器。 如果由于任何原因失去了控制器连接,则需要重新登录。

控制器保存有关允许不同用户执行哪些操作的信息。 UAS配置在RobotStudio中完成。     技巧

要了解有关UAS的更多信息,请使用RobotStudio中的帮助功能。 从自定义应用程序访问UAS 通过使用控制器对象上的属性AuthorizationSystem来访问UAS: VB: Dim uas As UserAuthorizationSystem = aController.AuthenticationSystem C#: UserAuthorizationSystem uas = aController.AuthenticationSystem; Grants and Groups UAS的权利称为授予。 特定用户属于几个已定义的组之一,其中每个组都有许多指定的授权。

为确保您具有执行操作所必需的授权,请在AuthorizationSystem对象上使用CheckDemandGrant方法。 检查授权作为参数传递: VB: If uas.CheckDemandGrant(Grant.LoadRapidProgram) Then aTask.LoadModuleFromFile(localFile, RapidLoadMode.Replace) End If C#: if (uas.CheckDemandGrant(Grant.LoadRapidProgram)) {aTask.LoadModuleFromFile(localFile, RapidLoadMode.Replace);} 注意 PC SDK应用程序无法覆盖UAS配置。 这意味着系统最终将阻止您执行不允许的操作。 MessageBox回馈 如果缺少UAS赠款,则应将其告知您。 可以在此示例中显示的消息中完成: msg = “You are not allowed to perform this operation, talk to your system administrator if you need access.” title = “User Authorization System” MessageBox.Show(msg, title, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); GetCurrentGrants和DemandGrant 另一种可能性是检索调用GetCurrentGrants的当前用户的所有授予,然后遍历Grants集合并搜索必要的授予。

另一个解决方案是用一个静态的Grant成员之一来调用DemandGrant,就像在参数中那样。

如果您没有指定的授予,则PC SDK会引发GrantDemandRejectedException。 异常处理 概述: .NET编程语言提供了对异常处理的内置支持,这使程序可以在执行过程中检测错误并从错误中恢复。

在托管代码中,在未处理的异常之后,执行不能在同一线程中继续。 该线程终止,并且如果它是程序线程,则程序本身终止。 为避免这种情况,应使用准确的异常处理。

从控制器抛出的异常由PC SDK ExceptionManager处理,该异常经理将内部HRESULT转换为具有合理异常描述的.NET异常,然后再将其抛出到自定义应用程序层。 应用程序对这些异常的处理应适用于常规.NET规则。

从性能的角度来看,异常的代价很高,如果有其他选择,则应避免例外。 如果可能,请使用try-finally块来清理系统和非托管资源分配。 Try-catch-finally 异常在try-catch(-finally)块中处理,这些块在正常的控制流程之外执行。

try块包装一个或几个要执行的语句。 如果此块中发生异常,则执行跳转到catch块,该块将处理该异常。

退出Try块时,无论是否发生异常并进行处理,都将执行finally块。 它用于清理系统或控制器资源。

如果您不知道会发生什么异常或如何处理它们,则可以捕获它们并且什么也不做。 但是,这可能会导致难以跟踪错误,因为异常包括有关导致问题的原因的信息。 因此,通过使用消息框或类型Debug或Trace,至少尝试显示异常消息。 类型转换 例如,当类型转换Signal或RapidData值时,存在类型转换异常的潜在风险。 为避免这种情况,您可以使用is运算符检查值和引用类型的对象: VB: If TypeOf aRapidData.Value Is Num Then Dim aNum As Num = DirectCast(aRapidData.Value, Num) … End If C#: if (aRapidData.Value is Num) { Num aNum = (Num)aRapidData.Value;… } 在C#中,也可以对引用类型使用as运算符。 如果类型不是预期的类型,则返回一个空值: C#: DigitalSignal di = this.aController.IOSystem.GetSignal(“UserSig”) as DigitalSignal; if (di == null) { MessageBox.Show(this, null, “Wrong type”); } .NET最佳做法 .NET Framework开发人员指南提供了以下异常处理最佳实践:

知道何时设置try / catch块。 例如,在不使用异常处理的情况下以编程方式检查可能发生的条件可能是一个更好的主意。 对于例行发生的错误,建议使用此方法,因为处理异常需要更长的时间。

使用异常处理来捕获意外错误。 如果事件确实是异常事件,并且是错误(例如意外的文件结尾),则异常处理是更好的选择,因为在通常情况下执行的代码较少。 最不具体。 此技术在将特定异常传递到更通用的catch块之前对其进行处理。 应用PC SDK Controller API PC SDK域介绍 PC SDK类库有以下域: Controllers ConfigurationDomain Discovery EventLogDomain FileSystemDomain Hosting IOSystemDomain Messaging MotionDomain RapidDomain UserAuthorizationManagement CAPI图 用于访问机器人控制器功能的类共同构成了控制器API(CAPI)。 下图显示了CAPI对象模型的一部分:

PC SDK参考 本应用程序手册涵盖了PC SDK的某些功能,但绝不是PC SDK的API的完整指南。

参考手册PC SDK是PC SDK类库的完整参考。 它应该是您编程时的伴侣。

可以从Windows“开始”菜单中指向程序-ABB Industrial IT-Robotics IT-RobotStudio 5.xx-SDK并选择PC SDK Reference来启动它。 创建一个简单的PC SDK应用程序 概述 要开始编程,请创建一个简单的应用程序,以显示网络上的所有虚拟和实际控制器。 然后应该可以登录到控制器并开始执行RAPID。

警告

必须小心处理对控制器的远程访问。 确保您不会无意间干扰生产中的系统。 设置项目 使用以下过程来设置PC SDK项目: Step Action 1 在Visual Studio中的“文件”菜单上,选择“新建”,然后单击“项目”。 选择一个Windows应用程序项目。 2 将对PC SDK程序集的引用ABB.Robotics.dll和ABB.Robotics.Controllers.dll添加到项目中。 程序集位于安装目录中,默认情况下位于C:\ Program Files \ ABB Industrial IT \ Robotics IT \ SDK \ PC SDK5.xx。 3 打开Form1.cs并在源代码页面的顶部添加所需的名称空间语句: VB: Imports ABB.Robotics Imports ABB.Robotics.Controllers Imports ABB.Robotics.Controllers.Discovery Imports ABB.Robotics.Controllers.RapidDomain C#: using ABB.Robotics; using ABB.Robotics.Controllers; using ABB.Robotics.Controllers.Discovery; using ABB.Robotics.Controllers.RapidDomain; 4 在解决方案资源管理器中,右键单击Form1.cs,然后选择“视图设计器”。 根据下一节中的说明创建图形用户界面。 创建用户界面 以下屏幕截图显示了我们将创建的正在运行的PC SDK应用程序。 如您所见,网络扫描中包括网络上的虚拟控制器和实际控制器。

使用以下过程创建应用程序的用户界面: Step Action 1 将表单的“文本”属性更改为“网络扫描窗口”。 2 将其大小更改为850; 480。 3 将ListView控件添加到窗体。 设置以下属性以获得与上图类似的外观: FullRowSelect - True GridLines - True View - Details 4 添加IPAdress,ID,可用性,虚拟,系统名称,RobotWare版本和控制器名称的列,并调整列的宽度。 5 在列表视图下添加带有按钮的面板。 设置按钮的文本。 实施网络扫描 为了找到网络上的所有控制器,我们首先在类Form1中声明这些成员变量。 VB: Private scanner As NetworkScanner = Nothing Private controller As Controller = Nothing Private tasks As Task() = Nothing Private networkWatcher As NetworkWatcher = Nothing C#: private NetworkScanner scanner = null; private Controller controller = null; private Task[] tasks = null; private NetworkWatcher networkwatcher = null; 由于应用程序应该在网络启动后立即对其进行扫描,因此我们可以将其代码放入Form1_Load事件处理程序中,如下所示: VB: Me.scanner = New NetworkScanner Me.scanner.Scan() Dim controllers As ControllerInfoCollection = Me.scanner.Controllers Dim controllerInfo As ControllerInfo = Nothing Dim item As ListViewItem For Each controllerInfo In controllers item = New ListViewItem(controllerInfo.IPAddress.ToString()) item.SubItems.Add(controllerInfo.Id) item.SubItems.Add(controllerInfo.Availability.ToString()) item.SubItems.Add(controllerInfo.IsVirtual.ToString()) item.SubItems.Add(controllerInfo.SystemName) item.SubItems.Add(controllerInfo.Version.ToString()) item.SubItems.Add(controllerInfo.ControllerName) Me.listView1.Items.Add(item) item.Tag = controllerInfo Next C#: this.scanner = new NetworkScanner(); this.scanner.Scan(); ControllerInfoCollection controllers = scanner.Controllers; ListViewItem item = null; foreach (ControllerInfo controllerInfo in controllers) { item = new ListViewItem(controllerInfo.IPAddress.ToString()); item.SubItems.Add(controllerInfo.Id); item.SubItems.Add(controllerInfo.Availability.ToString()); item.SubItems.Add(controllerInfo.IsVirtual.ToString()); item.SubItems.Add(controllerInfo.SystemName); item.SubItems.Add(controllerInfo.Version.ToString()); item.SubItems.Add(controllerInfo.ControllerName); this.listView1.Items.Add(item); item.Tag = controllerInfo; } 添加网络观察者 通过实施NetworkWatcher,应用程序可以监督网络并检测何时丢失或添加了控制器。 本示例说明如何对网络监控进行编程,以及如何将检测到的控制器添加到列表视图。

在将NetworkWatcher对象添加到FormLoad事件处理程序之后,我们向其Found事件添加了一个预订。 VB: Me.networkWatcher = New NetworkWatcher(Me.scanner.Controllers) AddHandler Me.networkWatcher.Found, AddressOf Me.HandleFoundEvent AddHandler Me.networkWatcher.Lost, AddressOf Me.HandleLostEvent Me.networkWatcher.EnableRaisingEvents = True C#: this.networkwatcher = new NetworkWatcher(scanner.Controllers); this.networkwatcher.Found += new EventHandler(HandleFoundEvent); this.networkwatcher.Lost += new EventHandler(HandleLostEvent); this.networkwatcher.EnableRaisingEvents = true; 注意 在C#中,在以上语句中的“ + =”之后,使用Tab键两次自动生成事件处理程序框架。 如果愿意,可以在使用通用事件处理程序时使用简化的语法: networkwatcher.Found + = HandleFoundEvent; 处理事件 由于事件将在后台线程上接收,并会导致用户界面更新,因此必须在事件处理程序中调用Invoke方法。 有关如何从后台强制执行到GUI线程的更多信息,请参见Invoke方法。 VB: Private Sub HandleFoundEvent(ByVal sender As Object, ByVal e As NetworkWatcherEventArgs) Me.Invoke(New EventHandler(Of NetworkWatcherEventArgs)(AddControllerToListView), New Object {Me, e}) End Sub C#: void HandleFoundEvent(object sender, NetworkWatcherEventArgs e) { this.Invoke(new EventHandler(AddControllerToListView), new Object[] { this, e }); } 此事件处理程序将更新用户界面: VB: Private Sub AddControllerToListView(ByVal sender As Object, ByVal e As NetworkWatcherEventArgs) Dim controllerInfo As ControllerInfo = e.Controller Dim item As New ListViewItem(controllerInfo.IPAddress.ToString()) item.SubItems.Add(controllerInfo.Id) item.SubItems.Add(controllerInfo.Availability.ToString()) item.SubItems.Add(controllerInfo.IsVirtual.ToString()) item.SubItems.Add(controllerInfo.SystemName) item.SubItems.Add(controllerInfo.Version.ToString()) item.SubItems.Add(controllerInfo.ControllerName) Me.listView1.Items.Add(item) item.Tag = controllerInfo End Sub C#: private void AddControllerToListView(object sender,NetworkWatcherEventArgs e) { ControllerInfo controllerInfo = e.Controller; ListViewItem item = new ListViewItem(controllerInfo.IPAddress.ToString()); item.SubItems.Add(controllerInfo.Id);item.SubItems.Add(controllerInfo.Availability.ToString()); item.SubItems.Add(controllerInfo.IsVirtual.ToString()); item.SubItems.Add(controllerInfo.SystemName); item.SubItems.Add(controllerInfo.Version.ToString()); item.SubItems.Add(controllerInfo.ControllerName); this.listView1.Items.Add(item); item.Tag = controllerInfo; } 建立与控制器的连接 双击列表中的控制器时,应建立与该控制器的连接,并应登录。 使用以下过程来实现功能: Step Action 1 生成ListView的DoubleClick事件。 2 在事件处理程序中,创建一个表示所选机器人控制器的Controller对象。 3 登录到选定的控制器。 有关更多信息,请参见Implement事件处理程序的代码示例。 Implement事件处理程序 此示例显示ListView.DoubleClick事件处理程序的代码: VB: Dim item As ListViewItem = Me.listView1.SelectedItems(0) If item.Tag IsNot Nothing Then Dim controllerInfo As ControllerInfo = DirectCast(item.Tag, ControllerInfo) If controllerInfo.Availability = Availability.Available Then If Me.controller IsNot Nothing Then Me.controller.Logoff() Me.controller.Dispose() Me.controller = Nothing End If Me.controller = ControllerFactory.CreateFrom(controllerInfo) Me.controller.Logon(UserInfo.DefaultUser) Else MessageBox.Show(“Selected controller not available.”) End If End If C#: ListViewItem item = this.listView1.SelectedItems[0]; if (item.Tag != null) { ControllerInfo controllerInfo = (ControllerInfo)item.Tag; if (controllerInfo.Availability == Availability.Available) { if (this.controller != null) { this.controller.Logoff(); this.controller.Dispose(); this.controller = null; } this.controller = ControllerFactory.CreateFrom(controllerInfo); this.controller.Logon(UserInfo.DefaultUser); } else { MessageBox.Show(“Selected controller not available.”); } } 注意 检查Controller对象是否已经存在很重要,因为在创建新对象之前,您应明确注销并处置所有现有Controller对象。 原因是登录会话分配的资源不应保留超过必要的时间。 开始执行程序 启动RAPID程序按钮的Click事件处理程序应启动第一个RAPID任务的程序执行。

在FlexPendant中只能以手动模式启动RAPID执行,因此在尝试之前,我们需要检查控制器是否处于自动模式。 然后,我们需要请求Rapid的主控权并调用Start方法。 如果已经由我们自己或其他客户端掌握了所有权,则将引发InvalidOperationException。 有关更多信息,请参见Mastership。

无论启动操作成功与否,都必须释放主控权。 可以通过在finally子句中调用Release()或Dispose()来完成,如VB示例所示,或者通过应用using机制(如C#示例所示)来完成。 VB: Private Sub button1_Click(ByVal sender As Object, ByVal e As EventArgs) Try If controller.OperatingMode = ControllerOperatingMode.Auto Then tasks = controller.Rapid.GetTasks() Using m As Mastership = Mastership.Request(controller.Rapid) 'Perform operation tasks(0).Start() End Using Else MessageBox.Show(“Automatic mode is required to start execution from a remote client.”) End If Catch ex As System.InvalidOperationException MessageBox.Show(“Mastership is held by another client.” & ex.Message) Catch ex As System.Exception MessageBox.Show("Unexpected error occurred: " & ex.Message) End Try End Sub C#: private void button1_Click(object sender, EventArgs e) { try { if (controller.OperatingMode == ControllerOperatingMode.Auto) { tasks = controller.Rapid.GetTasks(); using (Mastership m =Mastership.Request(controller.Rapid)) { //Perform operation tasks[0].Start(); } } else { MessageBox.Show(“Automatic mode is required to start execution from a remote client.”); } } catch (System.InvalidOperationException ex) { MessageBox.Show(“Mastership is held by another client.” + ex.Message); } catch (System.Exception ex) { MessageBox.Show("Unexpected error occurred: " + ex.Message); } } Discovery domain 概述 要从PC SDK应用程序创建到控制器的连接,它必须利用发现名称空间的Netscan功能。 必须创建NetworkScanner对象,并且必须执行扫描调用。

为了使PC SDK建立连接,必须在托管PC SDK应用程序的PC上安装RobotStudio或Robot Communications Runtime。 如果未安装RobotStudio,则可以从C:\ Program Files \ ABB Industrial IT \ Robotics IT \ SDK \ PC SDK 5.xx \ Redistributable \ RobotCommunicationRuntime安装Robot Communications Runtime。

要找出网络上可用的控制器,请使用NetworkScanner方法Scan,Find,GetControllers和GetRemoteControllers。 NetworkScanner 可以在类级别声明和表示NetworkScanner类。 在调用Scan方法之前,不会进行任何扫描。 调用GetControllers方法时,将返回ControllerInfo对象的集合。 每个这样的对象都保存有关连接到局域网的特定控制器的信息。 通过这种方式可以检测到虚拟控制器和实际控制器。 VB:

Private aScanner As NetworkScanner = New NetworkScanner

…’ Somewhere in the code

aScanner.Scan()

Dim aCollection As ControllerInfo() = aScanner.GetControllers()

C#:

private NetworkScanner aScanner = new NetworkScanner();

… // Somewhere in the code

aScanner.Scan();

ControllerInfo[] aCollection = aScanner.GetControllers();

如果只关注真实控制器,则可以先扫描网络,然后使用GetControllers方法中的NetworkScannerSearchCriterias枚举仅请求真实控制器。 VB: Dim aCollection As ControllerInfo() = aScanner.GetControllers(NetworkScannerSearchCriterias.Real) C#: ControllerInfo[] aCollection = aScanner.GetControllers(NetworkScannerSearchCriterias.Real); 如果知道要连接到哪个控制器系统,则可以调用Find方法,该方法在网络上查找指定的控制器。 它以系统ID作为System.Guid数据类型作为参数。 可以在机器人系统文件系统的INTERNAL文件夹中的system.guid文件中找到系统的全局唯一标识符(GUID)。 ControllerInfo object 执行网络扫描时,将返回ControllerInfo对象的集合。 ControllerInfo对象具有有关可用性的信息。 请记住,控制器状态更改时,不会更新ControllerInfo对象。 如果再次需要查找控制器是否可用,则需要执行新的网络扫描或使用现有的Controller对象并直接检查状态。 从本地局域网外添加控制器 仅在本地网络上进行网络扫描。 要检测本地网络之外的控制器,您需要使用静态AddRemoteController方法或在App.config文件中对其进行配置,以提供控制器的IP地址。 有关更多信息,请参见PC应用程序配置。

如果提供控制器IP地址,则可以使用字符串参数或System.Net.IPAddress对象。 VB: Dim ipAddress As System.Net.IPAddress Try ipAddress = System.Net.IPAddress.Parse(Me.textBox1.Text) NetworkScanner.AddRemoteController(ipAddress) Catch ex As FormatException Me.textBox1.Text = “Wrong IP address format” End Try C#: System.Net.IPAddress ipAddress; try { ipAddress = System.Net.IPAddress.Parse(this.textBox1.Text); NetworkScanner.AddRemoteController(ipAddress); } catch (FormatException ex) { this.textBox1.Text = “Wrong IP address format”; } NetworkWatcher 通过使用NetworkWatcher对象,您可以监督网络更改并找出何时发现新控制器或何时丢失控制器。 有关完整的代码示例,请参阅添加网络观察程序。 访问控制器 控制器对象 通过使用Controller对象,您可以访问机器人控制器的不同域,例如IO信号,RAPID,文件系统和elog消息。

要创建Controller对象,通常需要调用ControllerFactory: VB: Dim info As New ControllerInfo(New Guid(“systemid”)) Dim aController As Controller aController = ControllerFactory.CreateFrom(info) C#: ControllerInfo info = new ControllerInfo(new Guid(“systemid”)); Controller aController; aController = ControllerFactory.CreateFrom(info); 该参数是一个ControllerInfo对象,它可能已在网络扫描期间检索到,请参阅NetworkScanner。如果应该使用控制器的IP地址或系统ID(guid),也可以添加可选参数。

如果PC应用程序应与单个控制器一起使用,则可以在app.config文件中指定它。然后可以使用默认构造函数创建控制器对象,例如aController = new Controller()。有关更多信息,请参见。

如果您的应用程序中的多个类需要访问控制器,则建议它们都引用相同的Controller对象。这可以通过将Controller对象作为参数传递给构造函数,也可以使用Controller属性来完成。

注意

您应该知道,为对机器人控制器进行操作而创建的.NET对象将访问本机资源(C ++和COM代码)。 .NET垃圾收集器不会收集此类对象,但是必须由应用程序程序员显式处理这些对象。有关更多信息,请参阅访问控制器。 PC应用程序中的内存管理 .NET运行时环境的一个重要功能是垃圾收集器,该垃圾收集器从托管堆中回收未引用的内存。通常,这意味着程序员不必释放通过使用new分配的内存。但是,无法确切知道何时执行垃圾回收。

对于PC应用程序,不确定的资源分配通常不是问题(与FlexPendant应用程序相对,FlexPendant应用程序在内存有限的小型设备上运行)。但是,可在PC应用程序中使用IDisposable接口来获得确定性的资源分配。使用此接口,可以显式调用任何一次性对象的Dispose方法。

如果您的应用程序在单线程单元(STA)中运行,则Dispose调用将处理托管对象,但本地资源(由PC SDK在内部创建)将保留。要释放这些本机对象,应定期调用ReleaseUnmanagedResources方法,例如,当您单击某个按钮或每次将数据写入控制器时,都应调用该方法。方法调用并不昂贵。

对于在多线程单元(MTA)中运行的应用程序,Dispose调用将同时删除托管对象和本机对象。

注意

应该不时调用一次Controller.ReleaseUnmanagedResources方法,以避免在STA中运行的PC SDK应用程序中发生内存泄漏。 Dispose 它是一次性对象的创建者,负责其生命周期并负责调用Dispose。 应该检查对象是否仍然存在,并在Dispose调用之前删除对控制器事件的所有预订。 这是您处置Controller对象的方式: VB: If aController IsNot Nothing Then aController.Dispose() aController = Nothing End If C#: if (aController != null) { aController.Dispose(); aController = null; } Logon and logoff 在访问机器人控制器之前,PC SDK应用程序必须登录到控制器。 Logon方法的UserInfo参数具有可以使用的DefaultUser属性。 默认情况下,所有机器人系统都具有配置的此类用户。 VB: aController.Logon(UserInfo.DefaultUser) C#: aController.Logon(UserInfo.DefaultUser); 如果您的应用程序需要处理具有不同权限的用户,则可以使用UserAuthorizationManagement命名空间或使用RobotStudio中的UAS管理工具来配置这些用户。 这是您创建用于登录目的新UserInfo对象的方式。 注意 最晚在应用程序关闭时必须从控制器注销。 VB: AController.LogOff() C#: aController.LogOff(); 控制权 为了获得对某些控制器域的写访问权,应用程序必须请求主控权。 Rapid域(即机器人系统中存在的任务,程序,模块,例程和变量)就是这样一种域。 配置域是另一个。

有关更多信息,请参见Mastership。

进行修改操作后释放主控权非常重要。 一种实现方法是应用using语句,该语句导致在块末尾自动处置Mastership对象。 另一种可能性是在Final块中释放主控权,此块在Try和Catch块之后执行。 在“开始”程序执行示例中查看如何进行编码。 控制器事件 Controller对象提供了几个公共事件,使您可以侦听操作模式的更改,控制器状态的更改,主控权的更改等。 VB: AddHandler AController.OperatingModeChanged, AddressOf OperatingModeChanged AddHandler AController.StateChanged, AddressOf StateChanged AddHandler AController.ConnectionChanged, AddressOf ConnectionChanged C#: AController.OperatingModeChanged += new EventHandler(OperatingModeChanged); AController.StateChanged += new EventHandler(StateChanged); AController.ConnectionChanged += new EventHandler(ConnectionChanged); 注意 控制器事件使用其自己的线程。 仔细研究Controller事件和线程,以避免线程冲突。   注意 PC SDK 5.09及更高版本使用.NET Framework 2.0引入的常规事件处理。   警告 设置/激活控制器事件时,不要依赖于接收初始事件。 无法保证会触发事件,因此最好从控制器读取初始状态。 备份还原 使用Controller对象,可以调用Backup方法。 该参数是一个字符串,描述了控制器上应将备份存储在其中的目录路径。 您还可以还原以前备份的系统。 这需要掌握“快速”和“配置”的权限,并且只能在“自动”模式下完成。

备份样本 由于备份过程是异步执行的,因此您可以添加事件处理程序,以在备份完成后接收BackupCompleted事件。 备份目录应在系统备份目录中创建,否则将引发异常。 VB: Dim backupDir As String = “(BACKUP)KaTeX parse error: Expected 'EOF', got '&' at position 3: " &̲ backupDirName …” + backupDirName; this.aController.BackupCompleted += new EventHandler(aController_BackupCompleted); this.aController.Backup(backupDir); 恢复样本 Restore方法是同步的,也就是说,在还原操作完成之前,不会继续执行。 VB: Dim restoreDir As String = “(BACKUP)KaTeX parse error: Expected 'EOF', got '&' at position 3: " &̲ dirName Using…” + dirName; using (Mastership mc = Mastership.Request(this.aController.Configuration), mr = Mastership.Request(this.aController.Rapid)) { this.aController.Restore(restoreDir, RestoreIncludes.All, RestoreIgnores.All); } 注意

您需要登录才能获得上述功能。 虚拟面板 您可以使用VirtualPanel类及其ChangeMode方法以编程方式更改虚拟IRC5的操作模式。 这将阻塞应用程序线程,直到您使用Virtual FlexPendant手动接受模式更改为“自动”为止。 永久阻止应用程序线程的另一种方法是添加超时并使用try-catch块来捕获TimeoutException。 VB: Dim vp As VirtualPanel = VirtualPanel.Attach(aController) Try 'user need to acknowledge mode change on flexpendent vp.ChangeMode(ControllerOperatingMode.Auto, 5000) Catch ex As ABB.Robotics.TimeoutException Me.textBox1.Text = “Timeout occurred at change to auto” End Try vp.Dispose() C#: VirtualPanel vp = VirtualPanel.Attach(aController); try { //user need to acknowledge mode change on flexpendent vp.ChangeMode(ControllerOperatingMode.Auto, 5000); } catch (ABB.Robotics.TimeoutException ex) { this.textBox1.Text = “Timeout occurred at change to auto”; } vp.Dispose(); 也有异步方法调用BeginChangeOperatingMode和EndChangeOperatingMode。 在回调中使用第二种方法很重要,因为它会将等待线程返回到线程池。 VB: Dim vp As VirtualPanel = VirtualPanel.Attach(aController) vp.BeginChangeOperatingMode(ControllerOperatingMode.Auto, New AsyncCallback(ChangedMode), vp) C#: VirtualPanel vp = VirtualPanel.Attach(aController); vp.BeginChangeOperatingMode(ControllerOperatingMode.Auto, new AsyncCallback(ChangedMode), vp); 回调方法必须具有以下签名,并调用EndChangeOperatingMode并处理VirtualPanel。 VB: Private Sub ChangedMode(ByVal iar As IAsyncResult) Dim vp As VirtualPanel = DirectCast(iar.AsyncState, VirtualPanel) vp.EndChangeOperatingMode(iar) vp.Dispose() … End Sub C#: private void ChangedMode(IAsyncResult iar) { VirtualPanel vp = (VirtualPanel) iar.AsyncState; vp.EndChangeOperatingMode(iar); vp.Dispose(); … } Learn more、 本应用手册仅涵盖某些PC SDK功能。 为了充分发挥PC SDK的潜能,您应该使用PC SDK安装目录中的PC SDK参考。 有关更多信息,请参见PC SDK参考。

通过成为RobotStudio社区的活跃成员,您还可以学到很多东西。 当您发现自己无法解决自己的编码问题时,其PC SDK用户论坛应该是您的第一选择。 有关更多信息,请参见RobotStudio社区。 Using the PC SDK - Rapid domain 处理RAPID数据 概述 通过RapidDomain名称空间,可以访问机器人系统中的RAPID数据。 有许多PC SDK类代表不同的RAPID数据类型。 还有一个UserDefined类,用于引用RAPID中的RECORD结构。

当永久性RAPID数据已更改时,ValueChanged事件将启用来自控制器的通知。

为了加快来自控制器的事件通知,PC SDK 5.10中提供了一项新功能,该功能允许您设置订阅优先级。 这种可能性适用于I / O信号和持久性RAPID数据。 在实现高优先级数据订阅中进一步描述了此机制。

注意

要读取RAPID数据,您需要登录到控制器。 要修改RAPID数据,您还必须请求对Rapid域的所有权。 提供RAPID数据的路径 要读取或写入RAPID数据,必须首先创建一个RapidData对象。 控制器中数据声明的路径作为参数传递。 如果您不知道路径,则需要使用SearchRapidSymbol功能搜索RAPID数据。

直接访问 直接访问需要较少的内存并且速度更快,因此,如果以后不需要使用任务和模块对象,建议使用直接访问。

以下示例显示如何创建一个RapidData对象,该对象引用USER模块中的实例“ reg1”。 VB: Dim rd As RapidData = aController.Rapid.GetRapidData(“T_ROB1”, “user”, “reg1”) C#: RapidData rd = aController.Rapid.GetRapidData(“T_ROB1”, “user”, “reg1”); 分层访问 如果需要任务和模块对象,则分层访问可以更有效。 GetRapidData存在于Rapid,Task和Module类中。 VB: rd = aController.Rapid.GetTask(“T_ROB1”).GetModule(“user”). GetRapidData(“reg1”) C#: rd = aController.Rapid.GetTask(“T_ROB1”).GetModule(“user”). GetRapidData(“reg1”); 访问在共享模块中声明的数据 如果您的应用程序要与MultiMove系统(一个控制器和多个运动任务/机器人)一起使用,则可能会发生在共享RAPID模块中声明了您需要访问的RAPID实例。 这样的模块可用于所有任务T_ROB1,T_ROB2等。

以下示例显示如何创建一个引用实例“ reg100”的RapidData对象,该实例在共享模块中声明。 C#: Task tRob1 = aController.Rapid.GetTask(“T_ROB1”); if (tRob1 != null) { RapidData rData = tRob1.GetRapidData(“user”, “reg1”); } 注意

从RobotWare 5.12开始,即使在共享隐藏模块中声明了数据,PC SDK也可以访问它。 创建一个表示RAPID数据值的对象 RapidData对象存储RAPID数据的路径。 但是,如果您要访问它的值(至少要修改它),这还不够。 为此,您需要创建另一个对象,该对象代表RAPID数据的值。

在RapidDomain命名空间中,有一些类型代表不同的RAPID数据类型。 要创建表示RAPID数据值所需的对象,请使用RapidData属性Value并将其强制转换为相应的类型,例如Num,Bool或Tooldata。

要访问RAPID数据类型为bool的RAPID数据的值: VB: 'declare a variable of data type RapidDomain.Bool Dim rapidBool As ABB.Robotics.Controllers.RapidDomain.Bool Dim rd As ABB.Robotics.Controllers.RapidDomain.RapidData = aController.Rapid.GetRapidData(“T_ROB1”, “MainModule”, “flag”) 'test that data type is correct before cast If TypeOf rd.Value Is ABB.Robotics.Controllers.RapidDomain.Bool Then rapidBool = DirectCast(rd.Value, ABB.Robotics.Controllers.RapidDomain.Bool) 'assign the value of the RAPID data to a local variable Dim boolValue As Boolean = rapidBool.Value End If C#: //declare a variable of data type RapidDomain.Bool ABB.Robotics.Controllers.RapidDomain.Bool rapidBool; ABB.Robotics.Controllers.RapidDomain.RapidData rd = aController.Rapid.GetRapidData(“T_ROB1”, “MainModule”, “flag”); //test that data type is correct before cast if (rd.Value is ABB.Robotics.Controllers.RapidDomain.Bool) { rapidBool = (ABB.Robotics.Controllers.RapidDomain.Bool)rd.Value; //assign the value of the RAPID data to a local variable bool boolValue = rapidBool.Value; } 如果只想读取此变量,则可以使用以下技术来代替创建RapidDomain.Bool对象: VB: Dim b As Boolean = Convert.ToBoolean(rd.Value.ToString()) C#: bool b = Convert.ToBoolean(rd.Value.ToString()); 可以这样创建.NET类型的ToolData(代表RAPID数据类型tooldata): VB: Dim aTool As ToolData If TypeOf rd.Value Is ToolData Then aTool = DirectCast(rd.Value, ToolData) End If C#: ToolData aTool; if (rd.Value is ToolData) { aTool = (ToolData) rd.Value; } IRapidData.ToString方法 代表RAPID数据类型的所有RapidDomain结构都实现IRapidData接口。 它具有ToString方法,该方法以字符串形式返回RAPID数据的值。 这是一个简单的示例: string bValue = rapidBool.ToString(); 字符串按照IRapidData.FillFromString方法中描述的原理进行格式化。 以下是复杂数据类型的示例。 ToolDataTframe属性的类型为Pose。 其Trans值在标签中以[x,y,z]格式显示。 VB: Me.label1.Text = aTool.Tframe.Trans.ToString() C#: this.label1.Text = aTool.Tframe.Trans.ToString(); IRapidData.FillFromString方法 IRapidData接口还具有FillFromString方法,该方法用有效的RAPID字符串表示形式填充对象。 当您需要修改RAPID数据时,始终可以使用该方法。 在本章前面使用的带有RapidDomain.Bool变量的方法将看起来像这样:

rapidBool.FillFromString(“True”)

将其用于RapidDomain.Num变量类似于:

rapidNum.FillFromString(“10”) 字串格式 该格式是递归构造的。 以下示例对此进行了说明。 例: RapidDomain.Pose结构表示RAPID数据类型的位姿,它描述了一个坐标系如何围绕另一个坐标系位移和旋转。 public struct Pose : IRapidData { public Pos trans; public Orient rot; } 以下是RAPID中的示例: VAR pose frame1; … frame1.trans := [50, 0, 40]; frame1.rot := [1, 0, 0, 0]; 为frame1坐标变换指定一个值,该值对应于X = 50mm,Y = 0mm和Z = 40mm的位置的位移。 没有旋转。 RapidDomain.Pose结构包含两个结构变量,分别称为Pos和Orient数据类型的trans和rot。 Pos有三个花车,Orient由四个双花组成。 Pose对象的FillFromString格式为“ [[1.0,0.0,0.0,0.0] [10.0,20.0,30.0]]”。 该示例说明如何将新值写入RAPID姿势变量: VB: If TypeOf rd.Value Is Pose Then Dim rapidPose As Pose = DirectCast(rd.Value, Pose) rapidPose.FillFromString("[[1.0, 0.5, 0.0, 0.0][10, 15, 10]]") rd.Value = rapidPose End If C#: if (rd.Value is Pose) { Pose rapidPose = (Pose) rd.Value; rapidPose.FillFromString("[[1.0, 0.5, 0.0, 0.0][10, 15, 10]]"); rd.Value = rapidPose; } 注意

字符串格式必须仔细观察。 如果字符串参数格式错误,则将引发RapidDataFormatException。 写入RAPID数据 仅通过使用类型为RapidData的类型(已为其分配新值)的值来写入RAPID数据。 要将新值写入控制器中的RAPID数据,必须将.NET对象分配给RapidData对象的Value属性。 以下示例使用在创建表示RAPID数据值的对象中创建的RapidBool对象。 VB: 'Assign new value to .Net variable rapidBool.Value = False 'Request mastership of Rapid before writing to the controller Me.master = Mastership.Request(Me.aController.Rapid) 'Change: controller is repaced by aController rd.Value = rapidBool 'Release mastership as soon as possible Me.master.Dispose() C#: //Assign new value to .Net variable rapidBool.Value = false; //Request mastership of Rapid before writing to the controller this.master = Mastership.Request(this.aController.Rapid); //Change: controller is repaced by aController rd.Value = rapidBool; //Release mastership as soon as possible this.master.Dispose(); 有关控制器如何处理写访问权限的更多信息,请参见Mastership;有关在PC SDK应用程序中实现Mastership的另一个代码示例,请参见Start program execute。

前面的示例很简单,因为要更改的值很简单。 但是,RAPID通常使用复杂的结构。 通过使用FillFromString方法,您可以为任何RapidData分配一个新的Value并将其写入控制器。

字符串必须根据IRapidData中描述的原理进行格式化。 FillFromString部分。 以下示例说明如何将新值写入RAPID工具数据的pos结构(x,y,z):

VB:

Dim aPos As New Pos()

aPos.FillFromString("[2,3,3]")

aTool.Tframe.Trans = aPos

Using Mastership.Request(aController.Rapid)

rd.Value = aTool

End Using

C#:

Pos aPos = new Pos();

aPos.FillFromString("[2,3,3]");

aTool.Tframe.Trans = aPos;

using (Mastership.Request(aController.Rapid))

{

rd.Value = aTool;

}

注意

在执行最后一条语句之前,不会将新值写入控制器。 让用户知道RAPID数据已更改 为了得到RAPID数据已更改的通知,您需要为RapidData实例的ValueChanged事件添加一个预订。 但是,这仅适用于持久性RAPID数据。

添加订阅 这是您向ValueChanged事件添加订阅的方式: VB: AddHandler rd.ValueChanged, AddressOf rd_ValueChanged C#: rd.ValueChanged += new EventHandler(rd_ValueChanged); 处理事件 以下示例显示了事件处理程序的实现。 请记住,控制器事件使用其自己的线程,并通过使用Control.Invoke避免Winforms线程问题,该操作将强制从后台线程执行到GUI线程。 VB: Private Sub rd_ValueChanged(ByVal sender As Object, ByVal e As DataValueChangedEventArgs) Me.Invoke(New EventHandler(UpdateGUI), sender, e) End Sub C# private void rd_ValueChanged(object sender, DataValueChangedEventArgs e) { this.Invoke(new EventHandler(UpdateGUI), sender, e); } 要了解有关PC SDK应用程序中潜在的线程冲突的更多信息,请参阅控制器事件和线程。 从Controlller读取新值 用新值更新用户界面。 由于该值不是事件参数的一部分,因此必须使用RapidDataValue属性来检索新值: VB: Private Sub UpdateGUI(ByVal sender As Object, ByVal e As System.EventArgs) Dim tool1 As ToolData = DirectCast(Me.rd.Value, ToolData) Me.label1.Text = tool1.Tframe.Trans.ToString() End Sub C# private void UpdateGUI(object sender, System.EventArgs e) { ToolData tool1 = (ToolData)this.rd.Value; this.label1.Text = tool1.Tframe.Trans.ToString(); } 注意 订阅仅适用于声明为PETS的RAPID数据。 实施高优先级数据订阅 为了加快来自控制器的事件通知,可以为持久性RAPID数据设置订阅优先级。 为此,可以使用Subscribe方法和枚举EventPriority作为参数。 以下示例显示普通信号订阅和高优先级订阅: VB: AddHandler rd.ValueChanged, AddressOf rd_ValueChanged rd.Subscribe(rd_ValueChanged, EventPriority.High) C#: rd.ValueChanged += new EventHandler(rd_ValueChanged); rd.Subscribe(rd_ValueChanged, EventPriority.High); 要停用具有高优先级的订阅,可以按以下示例中所述调用Unsubscribe方法:

VB: rd.Unsubscribe(rd_ValueChanged) C#: rd.Unsubscribe(rd_ValueChanged); 注意

高优先级订阅可以用于声明为PERS的I / O信号和RAPID数据。 控制器可以处理64个高优先级订阅。

RapidData处理 建议您在不再需要RapidData对象时对其进行处置。 有关更多信息,请参见PC应用程序中的内存管理。 VB: If rd IsNot Nothing Then rd.Dispose() rd = Nothing End If C#: if (rd != null) { rd.Dispose(); rd = null; } 处理数组 概述 在RAPID中,最多可以有三个维数组。 可以像其他任何RAPID数据一样使用RapidData对象来访问这些对象。

访问数组的每个单独元素的方式主要有两种:通过索引器或通过枚举器。 ArrayData对象 如果RapidData引用的RAPID数组为Value属性,则返回ArrayData类型的对象。 在进行强制转换之前,请使用is运算符或使用RapidData对象上的IsArray属性检查类型。 VB: Dim rd As RapidData = aController.Rapid.GetRapidData(“T_ROB1”, “user”, “num_array”) If rd.IsArray Then Dim ad As ArrayData = DirectCast(rd.Value, ArrayData) … End If C#: RapidData rd = aController.Rapid.GetRapidData(“T_ROB1”, “user”, “num_array”); if (rd.IsArray) { ArrayData ad = (ArrayData)rd.Value; … } 数组尺寸 数组的维数由Rank属性返回。 如果需要检查单个数组的长度,则可以在ArrayData对象上使用GetLength方法,并将维度索引作为参数。 VB: Dim aRank As Integer = ad.Rank Dim len As Integer = ad.GetLength(aRank) C#: int aRank = ad.Rank; int len = ad.GetLength(aRank); 使用索引器访问数组项 通过使用索引器,即使在三维数组中,您也可以访问每个数组元素。 GetLength方法和For循环的组合使得可以访问任何项:

VB: Dim aSum As Double = 0R Dim aNum As Num Dim rd As RapidData = aController.Rapid.GetRapidData(“T_ROB1”, “user”, “num_array”) Dim ad As ArrayData = DirectCast(rd.Value, ArrayData) Dim aRank As Integer = ad.Rank If ad.Rank = 1 Then For i As Integer = 1 To ad.Length aNum = DirectCast(ad(i), Num) aSum += CDbl(aNum) Next ElseIf ad.Rank = 2 Then For i As Integer = 1 To ad.GetLength(0) For j As Integer = 1 To ad.Length aNum = DirectCast(ad(i, j), Num) aSum += CDbl(aNum) Next Next Else For i As Integer = 0 To ad.GetLength(0) - 1 For j As Integer = 0 To ad.GetLength(1) - 1 For k As Integer = 0 To ad.GetLength(2) - 1 aNum = DirectCast(ad(i, j, k), Num) aSum += CDbl(aNum) Next Next Next End If C#: double aSum = 0d;Num aNum;RapidData rd = aController.Rapid.GetRapidData(“T_ROB1”, “user”, “num_array”); ArrayData ad = (ArrayData)rd.Value;int aRank = ad.Rank;if (ad.Rank == 1){for (int i = 1; i RapidSymbolSearchProperties sProp = RapidSymbolSearchProperties.CreateDefault(); sProp.Recursive = true; sProp.Types = SymbolTypes.Constant | SymbolTypes.Persistent; sProp.SearchMethod = SymbolSearchMethod.Block; RapidSymbol[] rsCol = tRob1.SearchRapidSymbol(sProp, “RAPID/robtarget”, “p10”); RapidDataType theDataType; if (rsCol.Length > 0) { Console.WriteLine("RapidSymbol name = " + rsCol[0].Name); theDataType = RapidDataType.GetDataType(rsCol[0]); Console.WriteLine("DataType = " + theDataType.Name); if (theDataType.IsRecord) { RapidSymbol[] syms = theDataType.GetComponents(); SearchSymbolStructure(syms); } } } private void SearchSymbolStructure(RapidSymbol[] rsCol) { RapidDataType theDataType;foreach (RapidSymbol rs in rsCol){Console.WriteLine("RapidSymbol name = " + rs.Name);theDataType = RapidDataType.GetDataType(rs);Console.WriteLine("DataType = " + theDataType.Name);if (theDataType.IsRecord) { RapidSymbol[] syms = theDataType.GetComponents(); SearchSymbolStructure(syms); }} } The code example above produces the following printout: RapidSymbol name = p10 DataType = robtarget RapidSymbol name = trans DataType = pos RapidSymbol name = x DataType = num RapidSymbol name = y DataType = num RapidSymbol name = z DataType = num RapidSymbol name = rot DataType = orient RapidSymbol name = q1 DataType = num RapidSymbol name = q2 DataType = num RapidSymbol name = q3 DataType = num RapidSymbol name = q4 DataType = num RapidSymbol name = robconf DataType = confdata RapidSymbol name = cf1 DataType = num RapidSymbol name = cf4 DataType = num RapidSymbol name = cf6 DataType = num RapidSymbol name = cfx DataType = num RapidSymbol name = extax DataType = extjoint RapidSymbol name = eax_a DataType = num RapidSymbol name = eax_b DataType = num RapidSymbol name = eax_c DataType = num RapidSymbol name = eax_d DataType = num RapidSymbol name = eax_e DataType = num RapidSymbol name = eax_f DataType = num 实现代表记录的自己的结构 下面的示例演示如何在控制器中创建自己的.NET数据类型来表示RECORD,而不是使用UsefDefined类型。 创建ProcessData类型 VB: Dim rdt As RapidDataType = ctr.Rapid.GetRapidDataType(“T_ROB1”, “MyModule”, “processdata”) Dim pc As New ProcessData(rdt) pc.FillFromString(rd.Value.ToString()) C# RapidDataType rdt = ctr.Rapid.GetRapidDataType(“T_ROB1”, “MyModule”, “processdata”);ProcessData pc = new ProcessData(rdt);pc.FillFromString(rd.Value.ToString()); 实现ProcessData结构 以下示例显示了如何实现新的数据类型ProcessData。 这是通过使用.NET结构并让ProcessData包装UserDefined对象来完成的。

struct实现应包括FillFromString和ToString方法,即继承IRapidData接口。 任何特性和方法也可以实现。

VB: Public Structure ProcessData Implements IRapidData Private data As UserDefined Public Sub New(ByVal rdt As RapidDataType) data = New UserDefined(rdt) End Sub Private Property IntData() As UserDefined Get Return data End Get Set(ByVal Value As UserDefined) data = Value End Set End Property … End Structure C#: public struct ProcessData: IRapidData { private UserDefined data; public ProcessData(RapidDataType rdt) { data = new UserDefined(rdt); } private UserDefined IntData { get { return data; } set { data = value; } } public int StepOne { get { int res = Convert.ToInt32(IntData.Components[0].ToString()); return res; } set { IntData.Components[0] = new Num(value); } } }

实现IRapidData方法 这段代码显示了如何实现两个IRapidData方法ToString和FillFromString。

VB: Public Sub FillFromString(ByVal newValue As String) Implements ABB.Robotics.Controllers.RapidDomain.IRapidData.FillFromString IntData.FillFromString(newValue) End Sub Public Overrides Function ToString() As String Implements ABB.Robotics.Controllers.RapidDomain.IRapidData.ToString Return IntData.ToString() End Function C#: public void FillFromString(string newValue) { IntData.FillFromString(newValue); } public override string ToString() { return IntData.ToString(); } 注意! ToString方法必须在Visual Basic中使用Overrides关键字,在C#中必须使用override关键字。 Property implementation RECORD结构中的每个项目都应在扩展的.NET数据类型中具有相应的属性。 get和set方法必须实现从/到控制器数据类型到.NET数据类型的转换。 VB: Public Property Step() As Integer Get Dim res As Integer = Convert.ToInt32(IntData.Components(0).ToString()) Return res End Get Set(ByVal Value As Integer) Dim tmp As Num = New Num tmp.FillFromNum(Value) IntData.Components(0) = tmp End Set End Property C#: public int Step { get { int res = Convert.ToInt32(IntData.Components[0].ToString()); return res; } set { Num tmp = new Num(); tmp.FillFromNum(value); IntData.Components[0] = tmp; } } RAPID符号搜索 概述 大多数RAPID元素(变量,模块,任务,记录等)都是符号表的成员,它们的名称作为程序树结构的一部分存储在其中。

可以搜索此表并获得RapidSymbol对象的集合,每个对象都包括RAPID对象的名称,位置和类型。

搜索方式 由于系统中存在大量RAPID符号,因此必须仔细配置搜索。 要定义查询,您需要考虑应从程序树中的何处执行搜索,需要关注哪些符号以及需要哪些信息以获取感兴趣的符号。 为了启用从不同级别进行的搜索,SearchRapidSymbol方法是几种不同的SDK类的成员,例如Task,Module和Routine。 以下示例显示了以Task为起点执行的搜索:

VB: Dim RSCol As RapidSymbol() RSCol = ATask.SearchRapidSymbol(SProp, “num”, string.Empty) C#: RapidSymbol[] rsCol;rsCol = aTask.SearchRapidSymbol(sProp, “num”, string.Empty) SearchRapidSymbol方法具有三个参数。 下一节将详细介绍数据类型RapidSymbolSearchProperties的第一个参数。 以下各节将详细介绍第二个和第三个参数。

搜索属性 RapidSymbolSearchProperties类型很复杂,并且需要一些有关RAPID概念的知识。

它用于指定搜索方法,要搜索的RAPID符号的类型,搜索是否应递归,符号是本地的和/或全局的,以及搜索结果是否应仅包括程序当前使用的符号。 如果某个属性对特定符号无效,则该属性将被丢弃,并且不会从搜索结果中排除该符号。

下表描述了RapidSymbolSearchProperties的不同属性。

属性 描述 SearchMethod 指定搜索的方向,可以是“阻止”(向下)或“范围”(向上)。 示例:如果搜索的起点是例程,则块搜索将返回在例程中声明的符号,而范围搜索将返回可从例程访问的符号。 Types 指定要搜索的RAPID类型。 SymbolTypes枚举包括常量,变量,持久性,函数,过程,陷阱,模块,任务,例程,RapidData。 等等。 (例程包括函数,过程和陷阱。RapidData包括常量,变量和持久性。) Recursive 对于块搜索和范围搜索,都可以选择是在下一个范围或块级别停止搜索,还是递归地继续进行搜索,直到到达符号表树的根(或叶)为止。 GlobalSymbols 指定是否应包括全局符号。 LocalSymbols 指定是否应包含本地符号。 InUse 指定是否仅搜索已加载的RAPID程序正在使用的符号。

默认实例 RapidSymbolSearchProperties具有几个返回默认实例的静态方法。 VB: Dim SProp As RapidSymbolSearchProperties = RapidSymbolSearchProperties.CreateDefault() C#: RapidSymbolSearchProperties sProp = RapidSymbolSearchProperties.CreateDefault(); 默认实例具有以下值: 属性 描述 SearchMethod SymbolSearchMethod.Block Types SymbolTypes.NoSymbol Recursive True GlobalSymbols True LocalSymbols True InUse True

使用此实例,您可以指定要执行的搜索的搜索属性。

例: VB: SProp.SearchMethod = SymbolSearchMethod.Scope SProp.Types = SymbolTypes.Constant Or SymbolTypes.Persistent SProp.Recursive = False C#: sProp.SearchMethod = SymbolSearchMethod.Scope; sProp.Types = SymbolTypes.Constant | SymbolTypes.Persistent sProp.Recursive = false; 注意

默认实例的属性类型设置为NoSymbol。 必须指定它才能执行有意义的搜索!     注意

Types属性允许您在搜索中组合几种类型。 请参阅前面的示例。     注意

有关静态方法CreateDefaultForData和CreateDefaultForRoutine的信息,请参见PC SDK参考。

数据类型参数 SearchRapidSymbol方法的第二个参数是写为字符串的RAPID数据类型。 数据类型应使用小写字母,例如“ num”,“ string”或“ robtarget”。 也可以将其指定为string.Empty。

注意

要搜索UserDefined数据类型,必须传递包含RECORD定义的模块的完整路径。 例如:

result = tRob1.SearchRapidSymbol(sProp,“RAPID/T_ROB1/MyModule/MyDataType”, string.Empty); 但是,如果将MyModule配置为-Shared,则系统会看到其数据类型已安装,并且任务或模块不应包含在路径中 result = tRob1.SearchRapidSymbol(sProp,“MyDataType”, string.Empty); 符号名称参数 第三个参数是RAPID符号的名称。可以将其指定为string.Empty,如果未知的符号名称未知,或者目的是在系统中搜索所有“ num”数据。

可以使用正则表达式代替RAPID符号的名称。然后,搜索机制将使正则表达式的模式与符号表中的符号匹配。正则表达式字符串不区分大小写。

正则表达式是一种强大的机制。它可以包含普通字符和元字符。元字符是用于表示一个或几个普通字符的运算符,其目的是扩展搜索范围。

在正则表达式中,所有字母数字字符都匹配,即模式“ abc”将仅匹配名为“ abc”的符号。为了匹配所有包含字符序列“ abc”的符号名称,必须添加一些元字符。其正则表达式为“。* abc。*”。

可用的元字符集如下所示:

Expression Meaning . 任何单个字符 ^ 任何以开头的符号 [s] 非空集合s中的任何单个字符,其中s是字符序列。 范围可以指定为c-c。 [^s] 不在集合s中的任何单个字符。 r* 正则表达式r出现零次或多次。 r+ 正则表达式r出现一次或多次。 r? 正则表达式r出现零次或一次。 ® 正则表达式r。 用于将正则表达式与另一个分开。 r | r’ 正则表达式r或r’。 .* 任何字符序列(零个,一个或几个字符)。

例子1 “ ^ c。*”

返回以c或C开头的所有符号。

例子2 “ ^ reg [1-3]”

返回reg1,Reg1,REG1,reg2,Reg2,REG2,reg3,Reg3和REG3。

例子3 “ ^ c。* | ^ reg [1,2]”

返回以c或C开头的所有符号,以及reg1,Reg1,REG1,reg2,Reg2和REG2。

SearchRapidSymbol示例 本示例在任务及其模块中搜索VAR,PERS或CONST num数据。 搜索仅限于全局声明的符号。 默认情况下,搜索方法为“阻止”,因此不必设置。 VB: Dim sProp As RapidSymbolSearchProperties = RapidSymbolSearchProperties.CreateDefault() sProp.Types = SymbolTypes.Data sProp.LocalSymbols = False Dim rsCol As RapidSymbol() rsCol = aTask.SearchRapidSymbol(sProp, “num”, String.Empty) C#: RapidSymbolSearchProperties sProp = RapidSymbolSearchProperties.CreateDefault(); sProp.Types = SymbolTypes.Data; sProp.LocalSymbols = false; RapidSymbol[] rsCol; rsCol = aTask.SearchRapidSymbol(sProp, “num”, string.Empty);

搜索用户定义的RAPID数据-示例 在此示例中,在模块(“ myModule”)中声明了用户定义的RECORD数据类型(“ mydata”)。 假设最终用户可以在任何程序模块中声明和使用此数据类型的数据,则搜索方法必须为Block(默认)。 搜索所有“ mydata”实例可能看起来像这样:

VB: Dim sProp As RapidSymbolSearchProperties = RapidSymbolSearchProperties.CreateDefault() sProp.Types = SymbolTypes.Data Dim rsCol As RapidSymbol() rsCol = aTask.SearchRapidSymbol(sProp, “RAPID/T_ROB1/MyModule/mydata”, String.Empty) rsCol = aTask.SearchRapidSymbol(sProp, “mydata”, String.Empty) C#: RapidSymbolSearchProperties sProp = RapidSymbolSearchProperties.CreateDefault();sProp.Types = SymbolTypes.Data;RapidSymbol[] rsCol;rsCol = aTask.SearchRapidSymbol(sProp, “RAPID/T_ROB1/MyModule/mydata”, string.Empty);rsCol = aTask.SearchRapidSymbol(sProp, “mydata”, string.Empty); 注意

如果将myModule配置为-Shared,并且所有myData实例都在myModule中声明,则搜索方法必须设置为Scope,并且SearchRapidSymbol调用应如下所示:

rsCol = aTask.SearchRapidSymbol(sProp, “mydata”, string.Empty);

使用RAPID模块和程序 概述 使用Task对象可以加载和保存单个模块和程序。 您还可以卸载程序,以及重置程序指针并开始执行程序。

注意

所有这些操作都需要RAPID域的所有权。 有关更多信息,请参阅访问控制器。 加载模块和程序 要加载模块或程序文件,您需要控制器上文件的路径。 当文件加载到内存中时,RapidLoadMode枚举参数“添加”或“替换”指定是否应替换旧模块或程序。

如果文件扩展名不是有效的模块(mod或sys)或程序(pgf)扩展名,则会引发ArgumentException。

VB: Try aTask.LoadProgramFromFile(aPrgFileName, RapidLoadMode.Replace) aTask.LoadModuleFromFile(aModFileName, RapidLoadMode.Add) Catch ex As ArgumentException Return End Try C#: try { aTask.LoadProgramFromFile(aPrgFileName, RapidLoadMode.Replace); aTask.LoadModuleFromFile(aModFileName, RapidLoadMode.Add); } catch (ArgumentException ex) { return; } 注意

所有程序文件必须驻留在控制器的文件系统中,而不是在PC本地。 为了从PC加载程序,必须首先使用FileSystem.PutFile方法将其下载到控制器。 有关更多信息,请参见文件系统域。     注意

如果PC SDK应用程序使用了控制器的用户授权系统,则要求登录的用户具有UAS授权UAS_RAPID_LOADPROGRAM来加载和卸载RAPID程序。 有关特定PC SDK方法需要哪些授予的更多信息,请参见PC SDK参考。

保存程序和模块 您可以使用Task.SaveProgramToFile方法保存程序,也可以使用Module.SaveToFile方法保存单个模块。

要在将程序保存到文件后卸载程序,可以调用DeleteProgram()。

VB: Dim taskCol As Task() = aController.Rapid.GetTasks() For Each atask As Task In taskCol atask.SaveProgramToFile(saveDir) atask.DeleteProgram() Next C#: Task[] taskCol = aController.Rapid.GetTasks();foreach (Task atask in taskCol){atask.SaveProgramToFile(saveDir);atask.DeleteProgram();} 在此示例中,模块被保存到文件中: VB: Dim aModule As [Module] = aTask.GetModule(“user”) aModule.SaveToFile(aFilePath) C# Module aModule = aTask.GetModule(“user”);aModule.SaveToFile(aFilePath);

ResetProgramPointer方法 使用ResetProgramPointer,可以将程序指针设置为任务的主入口点。

VB: aTask.ResetProgramPointer() C#: aTask.ResetProgramPointer();

启动程序 只能在自动运行模式下在机器人控制器中启动程序执行。 有几种重载的Start方法可供使用,启动RAPID执行控制器任务的最简单方法是:

VB:

aTask.Start()

C#:

aTask.Start();

注意

如果您的应用程序使用控制器的用户授权系统(请参阅用户授权系统),则还应在调用Start方法之前检查当前用户是否具有UAS_RAPID_EXECUTE授予。

执行变更事件 可以订阅RAPID程序启动和停止时发生的事件。 这样做是这样的:

VB:

AddHandler aController.Rapid.ExecutionStatusChanged, AddressOf Rapid_ExecutionStatusChanged

C#

aController.Rapid.ExecutionStatusChanged += new EventHandler(Rapid_ExecutionStatusChanged);

有关如何编写由于控制器事件而更新GUI所需的事件处理程序的详细信息,请参阅避免线程冲突和让用户知道RAPID数据已更改。

使操作员能够从PC对RAPID UI指令做出响应 远程操作员对话框 当执行RAPID UI和TP指令时,PC SDK支持在PC而不是FlexPendant上启动操作员对话框。 在本章中,此功能称为“远程操作员对话框”。 它使操作员可以从PC而不是使用FlexPendant来提供RAPID程序所需的反馈。

注意

远程操作员对话框只能与RobotWare 5.12及更高版本一起使用。 支持的RAPID指令 支持以下RAPID指令: UIAlphaEntry UIListView UIMessageBox UIMsgBox UINumEntry UINumTune TPErase TPReadFK TPReadNum TPWrite

UIInstructionType PC SDK UIInstructionType枚举定义了上面列出的不同RAPID指令。 有关每种指令类型的说明,请参见《 PC SDK参考》。 以下是这种描述的示例。

示例UIInstructionType.UIAlphaEntry: Member Description UIAlphaEntry UIAlphaEntry(用户交互Alpha条目)用于允许操作员通过FlexAPIdant或PC SDK应用程序通过RAPID与机器人系统通信。 操作员输入文本后,可以通过调用UIAlphaEntryEventArgs.SendAnswer将其传输回RAPID程序。

技巧 有关RAPID中用法的完整信息,请参阅RAPID技术参考手册(可从RobotStudio访问)。 增加灵活性 通过使用远程操作员对话框功能,机器人系统的最终用户可以选择使用FlexPendant还是PC SDK应用程序来回答RAPID UI或TP指令。

FlexPendant将始终以常规方式显示操作员对话框。 如果操作员从PC响应,则FlexPendant上的消息将消失。

注意

如果操作员选择从FlexPendant进行响应,则PC SDK应用程序的对话框应消失。 这由PC SDK程序员处理。 基本方法 下面显示了在PC SDK应用程序中实现“远程操作员”对话框的基本过程。 FlexPendant在启动其操作员视图时在内部使用相同的方法。

Step Action 1 设置对UIInstructionEvent的订阅。 2 在事件处理程序中,从事件参数中检查UIInstructionEventType。 如果是Post或Send,则使用事件参数提供的信息来创建操作员对话框。 3 要将最终用户的响应转移到RAPID程序,请调用专门的UIInstructionEventArgs对象的SendAnswer方法。 4 如果获得UIInstructionEventType.Abort的UIInstructionEvent,请删除任何现有的运算符对话框。 注意

控制器事件始终在后台线程上接收,并且您需要在启动操作员对话框之前通过使用Invoke来强制执行GUI线程。 有关更多信息,请参见控制器事件和线程。 UIInstructionEvent 要在控制器中发生UI指令事件时收到通知,您需要设置UIInstructionEvent的订阅。 为此,您可以使用Rapid类的UIInstruction属性,如下所示:

Controller c = new Controller(); c.Rapid.UIInstruction.UIInstructionEvent += new UIInstructionEventHandler(OnUIInstructionEvent); UIInstructionEventArgs

UIInstructionEventArgs对象保存有关哪个RAPID任务以及哪个UI或TP指令触发了该事件的信息。 下图显示了所有UIInstructionEventArgs成员。

UIInstructionEventArgs是几个专门类的基类,每个UI-和TP-指令一个。 专用类包含创建操作员对话框所需的其他信息,因此必须将UIInstructionEventArgs对象类型转换为正确的专用类型。 为此,您首先要检查InstructionType属性,您可以在上图中看到它。

UIListViewEventArgs 作为特殊类型的示例,UIListViewEventArgs类的成员如下所示。 当然,Buttons和ListItems属性对于创建操作员对话框至关重要。

UIInstructionEventType 上图中的一个重要属性是UIInstructionEventType。 它从基类继承,并附带所有UI和TP指令事件。

下表显示了UIInstructionEventType枚举的成员。

Member Description Undefined 未定义。 不应该发生。 Post 发布事件类型,例如TPWrite,TPErase。 当事件属于此类型时,RAPID期望操作员没有响应。 Send 发送事件类型,例如TPReadNum,UIListView。 当事件属于此类时,正在运行的RAPID程序会在连续执行之前期待操作员的反馈。 Abort 当控制器从客户端(FlexPendant或PC SDK应用程序)获得响应时,它将发送中止类型的事件。 这告诉所有订阅客户端该UI指令已被操作员中止,关闭或确认。 当您收到此类事件时,应删除所有打开的操作员对话框。 注意

如果机器人系统具有多个RAPID任务,则必须跟踪哪个操作员对话框属于哪个任务,依此类推。

RAPID任务只能处理一个挂起的Send,并且不能保证Abort事件将始终跟随Send事件。 因此,如果从同一任务接收到新的Send事件而没有前面的Abortevent,则应删除现有对话框并显示新对话框。 SendAnswer方法 要将最终用户的响应传递回RAPID程序,可以调用SendAnswer方法。 请参见上面的UIListViewEventArgs类的图像。 根据RAPID指令,使用不同的参数调用SendAnswer。

例如,如果它是UIAlphaEntry指令,则可以发送操作员输入的字符串作为参数。 但是,如果它是UIListView指令,则SendAnswer方法将如下所示: public void SendAnswer(int listItemIdx, UIButtonResult btnRes); 注意

使用“远程操作员”对话框不涉及母带处理。

IO system domain 概述 机器人系统使用输入和输出信号来控制过程。 信号可以是数字,模拟或组信号类型。 可使用SDK访问此类IO信号。

机器人系统中的信号变化通常很重要,并且在许多情况下,系统的最终用户需要通知信号变化。

为了加快来自控制器的事件通知,PC SDK 5.10中提供了新功能,可让您设置订阅优先级。 这种可能性适用于I / O信号和持久性RAPID数据。 在实现高优先级事件订阅中进一步描述了此机制。 访问信号 通过Controller对象及其属性IOSystem来访问信号,该对象表示机器人控制器中的IO信号空间。

要访问信号,您需要信号的系统名称。 从IOSystem.GetSignal方法返回的对象的类型为Signal。

VB: Dim signal1 As Signal = aController.IOSystem.GetSignal(“signal_name”) C#: Signal signal1 = aController.IOSystem.GetSignal(“signal_name”); 返回的Signal对象必须类型转换为数字,模拟或组信号。 此示例说明如何创建DigitalSignal类型的信号: VB: Dim diSig As DigitalSignal = DirectCast(signal1, DigitalSignal) C#: DigitalSignal diSig = (DigitalSignal)signal1; 此示例显示了如何创建AnalogSignal: VB: Dim aiSig As AnalogSignal = DirectCast(Signal1, AnalogSignal) C#: AnalogSignal aiSig = (AnalogSignal)signal2 此示例说明如何创建GroupSignal: VB: Dim giSig As GroupSignal = DirectCast(signal3, GroupSignal) C#: GroupSignal giSig = (GroupSignal)signal3; 注意

切记在不再使用信号时调用该信号的Dispose方法。 使用SignalFilter获取信号 不仅可以一次获取一个信号,还可以使用信号滤波器来收集信号。 一些SignalFilter标志是互斥的,例如SignalFilter.Analog和SignalFilter.Digital。 其他包括在内,例如SignalFilter.Digital和SignalFilter.Input。 您可以使用“ |”组合过滤器标志 C#中的字符和VB中的Or运算符:

VB: Dim aSigFilter As IOFilterTypes = IOFilterTypes.Digital Or IOFilterTypes.Input Dim signals As SignalCollection = aController.IOSystem.GetSignals(aSigFilter) C#: IOFilterTypes aSigFilter = IOFilterTypes.Digital | IOFilterTypes.Input; SignalCollection signals = aController.IOSystem.GetSignals(aSigFilter); 以下代码迭代信号收集并将所有信号添加到ListView控件。 该列表有三列,显示信号名称,类型和值: VB: For Each signal As Signal In signals item = New ListViewItem(signal.Name) item.SubItems.Add(signal.Type.ToString()) item.SubItems.Add(signal.Value.ToString()) listView1.Items.Add(item) Next C#: foreach (Signal signal in signals) { item = new ListViewItem(signal.Name); item.SubItems.Add(signal.Type.ToString()); item.SubItems.Add(signal.Value.ToString()); listView1.Items.Add(item); } 如果不再需要信号对象,则应将其丢弃: VB: For Each signal As Signal In signals signal.Dispose() Next C#: foreach (Signal signal in signals) { signal.Dispose(); } 读取IO信号值 以下示例显示了如何读取数字和模拟信号。

数字信号 以下代码读取数字信号DO1并在信号值为1(ON)时选择一个复选框: VB: Dim sig As Signal = aController.IOSystem.GetSignal(“DO1”) Dim digitalSig As DigitalSignal = DirectCast(sig, DigitalSignal) Dim val As Integer = digitalSig.Get If val = 1 Then Me.checkBox1.Checked = True End If C#: Signal sig = aController.IOSystem.GetSignal(“DO1”); DigitalSignal digitalSig = (DigitalSignal)sig;int val = digitalSig.Get(); if (val == 1) {this.checkBox1.Checked = true;} 模拟信号 以下代码读取模拟信号AO1的值,并将其显示在文本框中: VB: Dim asig As Signal = aController.IOSystem.GetSignal(“AO1”) Dim analogSig As AnalogSigna = DirectCast(asig, AnalogSignal) Dim analogSigVal As Single = analogSig.Value Me.textBox1.Text = analogSigVal.ToString() C#: Signal asig = aController.IOSystem.GetSignal(“AO1”); AnalogSigna analogSig = (AnalogSignal)asig;float analogSigVal = analogSig.Value; this.textBox1.Text = analogSigVal.ToString(); 写入IO信号值 这节说明如何通过PC SDK应用程序修改数字或模拟IO信号的值。   注意 在手动模式下,仅当信号的访问级别为ALL时才能修改信号值。 如果不是,则控制器必须处于自动模式。 数字信号 当您选择/取消选择复选框时,以下代码将更改控制器中数字信号的值:

VB: Private Sub checkBox1_Click(ByVal sender As Object, ByVal e As EventArgs) If Me.checkBox1.Checked Then digitalSig.Set Else digitalSig.Reset() End If End Sub C#: private void checkBox1_Click(object sender, EventArgs e) { if (this.checkBox1.Checked) { digitalSig.Set(); } else { digitalSig.Reset(); } } 注意! 您也可以使用Value属性设置值。

模拟信号 以下代码将在文本框中输入的值写入模拟信号AO1。 将该值从字符串转换为浮点数,然后再将其写入控制器: VB: Dim analogSigVal As Single = Convert.ToSingle(Me.textBox1.Text) analogSig.Value = analogSigVal C#: float analogSigVal = Convert.ToSingle(this.textBox1.Text); analogSig.Value = analogSigVal;

监控信号变化 一旦Signal对象可用,便可以为其Changed事件添加预订,该预订在信号更改(例如,更改的值,更改的模拟状态或更改的信号质量)时触发。

Visual Basic Friend WithEvents sig As AnalogSignal … AddHandler sig.Changed, AddressOf sig_Changed … Private Sub sig_Changed(ByVal sender As Object, ByVal e As SignalChangedEventArgs) … End Sub C# sig.Changed += new EventHandler(sig_Changed); … private void sig_Changed(object sender, SignalChangedEventArgs e) {… } 开始和停止订阅 如果您在应用程序的整个生命周期中都不需要订阅,则建议您激活和停用对Changed事件的订阅: VB: AddHandler sig.Changed, AddressOf sig_Changed RemoveHandler sig.Changed, AddressOf sig_Changed C#: sig.Changed += new EventHandler(sig_Changed); sig.Changed -= new EventHandler(sig_Changed); 实施高优先级事件订阅 为了加快来自控制器的事件通知,可以为I / O信号设置订阅优先级。 为此,可以使用Subscribe方法和枚举EventPriority作为参数。 该示例显示了普通信号订阅和具有高优先级的订阅: VB: AddHandler signal.Changed, AddressOf sig_Changed signal.Subscribe(sig_Changed, EventPriority.High) C#: signal.Changed += new EventHandler(sig_Changed); signal.Subscribe(sig_Changed, EventPriority.High); 要停用具有高优先级的订阅,您可以像下面这样调用Unsubscribe方法: VB: signal.Unsubscribe(sig_Changed) C#: signal.Unsubscribe(sig_Changed);

高优先级事件的局限性 高优先级订阅可以用于声明为PERS的I / O信号和RAPID数据。 控制器可以处理64个高优先级订阅。

避免线程冲突 控制器事件使用其自己的线程,这些线程与应用程序GUI线程不同。 如果要在应用程序GUI中显示信号变化,可能会导致问题。 有关更多信息,请参见控制器事件和线程。

如果不需要更新用户界面,则无需执行任何特殊操作,但是可以在事件线程上执行事件处理程序。 但是,如果需要向用户显示信号已更改,则应使用Invoke方法。 它强制执行到窗口控制线程,从而为潜在的线程冲突提供了解决方案。

VB: Me.Invoke(New EventHandler(Of SignalChangedEventArgs)(UpdateUI), New Object {sender, e}) C#: this.Invoke(new EventHandler(UpdateUI), new Object[] { sender, e }); 读取新值 SignalChangedEventArgs对象具有NewSignalState属性,该属性具有有关信号值,信号质量以及是否仿真信号的信息: VB: Private Sub UpdateUI(ByVal Sender As Object, ByVal e As SignalChangedEventArgs) Dim state As SignalState = e.NewSignalState Dim val As Single Val = state.Value Me.textBox1.Text = val.ToString() … End Sub C#: private void UpdateUI(object sender, SignalChangeEventArgs e) { SignalState state = e.NewSignalState; … float val = state.Value this.textBox1.Text = val.ToString() } 注意

不能保证您在设置订阅时会收到初始事件。 要获取有关信号值的初始信息,应使用Value属性读取它。        注意

在处置信号之前,请确保已删除订阅。 有关更多信息,请参阅访问控制器。

事件日志域 概述: 事件日志消息可能包含有关控制器状态,RAPID执行,控制器正在运行的进程等信息。

使用SDK可以读取队列中的消息,也可以使用事件处理程序来接收每个新日志消息的副本。 事件日志消息包含队列类型,事件类型,事件时间,事件标题和消息。 访问控制器事件日志 您可以通过Controller属性EventLog访问事件日志域。

VB: Private log As EventLog = aController.EventLog C#: private EventLog log = aController.EventLog; 访问事件日志类别、 所有事件日志消息均按类别进行组织。 要搜索单个消息,您必须知道它属于哪个类别。 枚举类型CategoryType定义了所有可用的类别。 您可以通过使用GetCategory方法或使用Categories属性来获取类别,该属性是所有可用类别的数组。

VB: Dim cat As EventLogCategory cat = Log.GetCategory(CategoryType.Program) or cat = log.Categories(4) C#: EventLogCategory cat; cat = log.GetCategory(CategoryType.Program); or cat = log.GetCategory[4];

注意

当不再使用EventLogCategory时,应将其丢弃。 访问事件日志消息 要访问消息,请使用Category对象的Messages属性。 返回消息的集合。 该集合实现ICollection和IEnumerable接口,这意味着您可以对集合使用通用操作。 使用索引或使用foreach进行迭代即可完成访问。 VB: Dim msg As EventLogMessage = cat.Messages(1) or Dim msg As EventLogMessage For Each msg In cat.Messages Me.textBox1.Text = msg.Title … Next Item C#: EventLogMessage msg = cat.Messages[1];or foreach (EventLogMessage emsg in cat.Messages) { this.textBox1.Text = emsg.Title; … } MessageWritten事件 可以添加一个事件处理程序,该事件处理程序在将新消息写入控制器事件日志时得到通知。 这是通过订阅EventLog事件MessageWritten来完成的。

事件参数的类型为MessageWrittenEventArgs,并具有Message属性,该属性保存最新的事件日志消息。

VB: Private Sub log_MessageWritten(ByVal sender As Object, ByVal e As MessageWrittenEventArgs) Dim msg As EventLogMessage = e.Message End Sub C#: private void log_MessageWritten(object sender, MessageWrittenEventArgs e) { EventLogMessage msg = e.Message; } 注意

如果由于事件而需要更新应用程序用户界面,则必须使用Invoke方法将此作业委托给GUI线程。 有关更多信息和代码示例,请参阅控制器事件和线程。     技巧 在PC SDK参考帮助中找到有关EventLogDomain的更多信息。 Motion domain 概述 MotionDomain名称空间使您可以访问机器人系统的机械单元。

Motion system 您可以使用Controller属性MotionSystem访问运动系统。

VB: Private aMotionSystem As MotionSystem aMotionSystem = aController.MotionSystem C# private MotionSystem aMotionSystem; aMotionSystem = aController.MotionSystem;

例如,通过使用MotionSystem对象,可以使用其SpeedRatio属性查找机器人的当前速度。

访问机械单元 机械单元可以是不同类型,例如具有TCP的机器人,多轴机械手或单轴单元。 所有这些都可以通过MotionSystem属性MechanicalUnits获得。 如果仅对活动的机械单元感兴趣,则可以使用ActiveMechanicalUnit属性。

VB: Dim aMechCol As MechanicalUnitCollection = aController.MotionSystem.MechanicalUnits Dim aMechUnit As MechanicalUnit = aController.MotionSystem.ActiveMechanicalUnit C#: MechanicalUnitCollection aMechCol = aController.MotionSystem.MechanicalUnits; MechanicalUnit aMechUnit = aController.MotionSystem.ActiveMechanicalUnit; 机械单元的属性和方法 机械单元有许多可用的属性,例如Name,Model,NumberOfAxes,SerialNumber,CoordinateSystem,MotionMode,IsCalibrated,Tool和WorkObject等。 也可以将机械单元的当前位置作为RobTarget或JointTarget。

VB: Dim aRobTarget As RobTarget = aController.MotionSystem.ActiveMechanicalUnit.GetPosition(CoordinateSystemType.World) Dim aJointTarget As JointTarget = aController.MotionSystem.ActiveMechanicalUnit.GetPosition() C#: RobTarget aRobTarget = aController.MotionSystem.ActiveMechanicalUnit.GetPosition(CoordinateSystemType.World); JointTarget aJointTarget= aController.MotionSystem.ActiveMechanicalUnit. GetPosition();

技巧 要读取Rapid数据,即RobTarget和JointTarget,用户必须登录到控制器

在PC SDK参考帮助中找到有关MotionDomain的更多信息。

校准轴 使用机械方法MechanicalUnit.SetRevolutionCounter更新TCP机械单元的转数计数器。 例如,当断开控制系统并且移动机器人轴时,更新旋转计数器。

MechanicalUnit.GetMechanicalUnitStatus属性显示是否需要校准。

使用方法MechanicalUnit.FineCalibrate进行精细校准。

有关更多信息,请参见《参考手册PC SDK》。

FineCalibrate和SetRevolutionCounter要求系统处于FlexPendant的“自动模式和Motors off状态”或“手动模式并授予访问权限”。 FineCalibrate和SetRevolutionCounter也需要相应的UAS授予。

有关如何执行校准的更多信息,请参见《操作手册-带FlexPendant的IRC5》。

警告

如果旋转计数器的更新不正确,将导致机器人定位错误,进而造成损坏或伤害。

File system domain 概述 使用SDK可以在控制器文件系统中创建,保存,加载,重命名和删除文件。 也可以创建和删除目录。 访问文件和目录 您可以通过Controller属性FileSystem访问文件系统域。 VB: Dim aFileSystem As FileSystem = aController.FileSystem C#: FileSystem aFileSystem = aController.FileSystem;

控制器和PC目录 您可以使用RemoteDirectory和LocalDirectory属性在控制器和本地PC系统上获取并设置目录。

VB: Dim remoteDir As String = aController.FileSystem.RemoteDirectory Dim localDir As String = aController.FileSystem.LocalDirectory C#: string remoteDir = aController.FileSystem.RemoteDirectory; string localDir = aController.FileSystem.LocalDirectory; 环境变量 指定文件系统路径时,可以使用环境变量来表示当前使用的系统的HOME,系统,备份和临时目录。 当应用程序使用“(BACKUP)$”时,在内部将其解释为当前系统备份目录的路径。 其他环境变量是:HOME,TEMP和SYSTEM。

载入文件、 您可以使用GetFile方法将文件从控制器加载到PC。 如果操作无效,该方法将生成异常。 参数是完整的路径,包括文件名。 VB: aController.FileSystem.GetFile(remoteFilePath, localFilePath) C#: aController.FileSystem.GetFile(remoteFilePath, localFilePath); 保存文件 您可以使用PutFile方法将文件保存在控制器文件系统上。 如果操作无效,该方法将生成异常。 参数是完整的路径,包括文件名。 VB: aController.FileSystem.PutFile(localFilePath, remoteFilePath) C#: aController.FileSystem.PutFile(localFilePath, remoteFilePath); CopyFile和CopyDirectory PutFile / GetFile方法生成文件的副本,并将其传输到控制器文件系统或从控制器文件系统传输。 使用CopyFile和CopyDirectory可以直接在控制器上创建副本: VB: aController.FileSystem.CopyFile(fromFilePath, toFilePath, True) aController.FileSystem.CopyDirectory(fromDirPath, toDirPath, True) C#: aController.FileSystem.CopyFile(fromFilePath, toFilePath,true); aController.FileSystem.CopyDirectory(fromDirPath, toDirPath,true); 获取多个文件和目录 FileSystem类具有一个称为GetFilesAndDirectories的方法。 它可用于检索包含单个文件和目录信息的ControllerFileSystemInfo对象数组。 然后可以将ControllerFileSystemInfo对象强制转换为ControllerFileInfo对象或ControllerDirectoryInfo对象。

本示例使用搜索模式来限制搜索。

VB: Dim anArray As ControllerFileSystemInfo() Dim info As ControllerFileSystemInfo anArray = aController.FileSystem.GetFilesAndDirectories(“search pattern”) For i As Integer = 0 To anArray.Length - 1 info = anArray(i) … Next C#: ControllerFileSystemInfo[] anArray; ControllerFileSystemInfo info; anArray = aController.FileSystem.GetFilesAndDirectories(“search pattern”); for (int i=0;i myQueue = c.Ipc.CreateQueue(“PC_SDK_Q”, 5, Ipc.IPC_MAXMSGSIZE); myQueue = c.Ipc.GetQueue(“PC_SDK_Q”); } //Create IpcMessage objects for sending and receiving sendMessage = new IpcMessage(); recMessage = new IpcMessage(); … //in an event handler, eg. button_Click SendMessage(true); CheckReturnMsg(); … public void SendMessage(bool boolMsg) { Byte[] data = null; //Create message data if (boolMsg) { data = new UTF8Encoding().GetBytes(“bool;TRUE”); } else { data = new UTF8Encoding().GetBytes(“bool;FALSE”); } //Place data and sender information in message sendMessage.SetData(data); sendMessage.Sender = myQueue.QueueId; //Send message to the RAPID queue tRob1Queue.Send(sendMessage); } private void CheckReturnMsg() { IpcReturnType ret = IpcReturnType.Timeout; string answer = string.Empty; int timeout = 5000; //Check for msg in the PC SDK queue ret = myQueue.Receive(timeout, recMessage); if (ret == IpcReturnType.OK) { //convert msg data to string answer = new UTF8Encoding().GetString(recMessage.Data); MessageBox.Show(answer); //MessageBox should show: string;“Acknowledged” } else { MessageBox.Show(“Timeout!”); } } Rapid 将为数据类型为bool的消息创建一个陷阱。 在陷阱中,消息数据的值分配给标志变量。 然后,“确认”消息被发送回PC SDK客户端。 通常,将执行WHILE循环,直到收到具有TRUE值的消息为止。 MODULE RAB_COMMUNICATION VAR bool flag := FALSE; VAR intnum connectnum; PROC main() CONNECT connectnum WITH RABMsgs; IRMQMessage flag, connectnum; WHILE flag = FALSE DO !do something, eg. normal processing… WaitTime 3; ENDWHILE !PC SDK message received - do something… TPWrite “Message from PC SDK, will now…”; IDelete connectnum; EXIT; ENDPROC TRAP RABMsgs VAR rmqmessage msg; VAR rmqheader header; VAR rmqslot rabclient; VAR num userdef; VAR string ack := “Acknowledged”; RMQGetMessage msg; RMQGetMsgHeader msg \Header:= header\SenderId:=rabclient\UserDef:=userdef; !check data type and assign value to flag variable IF header.datatype = “bool” THEN RMQGetMsgData msg, flag; !return receipt to sender RMQSendMessage rabclient, ack; ELSE TPWrite “Unknown data received in RABMsgs…”; ENDIF ENDTRAP ENDMODULE 注意

错误处理应在C#和RAPID中实现。     注意

从RobotWare 5.12开始,有一条新的RAPID指令RMQEmptyQueue,可用于清空任务中的队列。 PC-调试和故障排除 Debugging Introduction 与标准.NET开发相比,将Visual Studio调试器用于PC SDK应用程序没有任何区别。 可以使用RobotStudio中的虚拟IRC5或实际控制器进行调试。

异常错误代码 在开发过程中可能出现的某些异常具有与之关联的错误代码。 错误代码可以帮助您解决问题。

Code Description 0x80040401 无法满足请求的轮询级别,已使用轮询级别低。 0x80040402 无法满足请求的轮询级别,使用的是轮询级别中。 0xC0040401 与控制器无连接。 0xC0040402 连接控制器时出错。 0xC0040403 控制器无响应。 0xC0040404 消息队列已满。 (仅在进行异步调用时才会发生。) 0xC0040405 等待资源。 0xC0040406 发送的消息太大,无法处理。 0xC0040408 字符串不包含专门来自受支持编码的字符,例如ISO-8859-1(ISO-Latin1)。 0xC0040409 由于资源正在使用中,因此无法释放。 0xC0040410 客户端已经以控制器用户身份登录。 0xC0040411 NetScan中不存在该控制器。 0xC0040412 NetScanID不再使用。 控制器已从列表中删除。 0xC0040413 客户端ID与控制器用户没有关联。 仅由在向控制器发送请求之前需要检查此方法的方法返回。 否则,请参见0xC004840F。 0xC0040414 RobotWare版本晚于已安装的Robot Communication Runtime。 需要安装更新的机器人通信运行时。 由RobHelperFactory返回。 0xC0040415 RobotWare版本的主要和次要部分是已知的,但是该修订版是以后的版本,并不完全兼容。 需要安装更新的机器人通信运行时。 RobHelperFactory返回的代码。 0xC0040416 不再支持RobotWare版本。 RobHelperFactory返回的代码。 0xC0040417 RobotWare不支持帮助程序类型。 Helper可能已过时或在更高版本的RobotWare中使用,或者BootLevel控制器可能不支持该Helper。 RobHelperFactory返回的代码。 0xC0040418 系统ID和网络ID不匹配,它们不能标识相同的控制器。 0xC0040601 调用是由其他客户端(而不是进行Connect()调用)进行的。 0xC0040602 在本地文件系统上找不到文件。可以是该文件,目录或设备不存在。 0xC0040603 在远程文件系统上找不到文件。可以是该文件,目录或设备不存在。 0xC0040604 在本地文件系统上访问/创建文件时出错。 0xC0040605 在远程文件系统上访问/创建文件时出错。 0xC0040606 路径或文件名太长,否则对于VxWorks文件系统来说是错误的。 0xC0040607 文件传输被中断。传输到远程系统时,原因可能是远程设备已满。 0xC0040608 本地设备已满。 0xC0040609 客户端已经建立连接,并且在断开当前连接之前无法建立新连接。 0xC0040701 发布目录中的一个或多个文件已损坏,启动VC时无法使用。 0xC0040702 启动VC时,系统目录中的一个或多个文件已损坏,无法使用。 0xC0040703 该系统的VC已经启动;每个系统仅允许一个VC。 0xC0040704 无法热启动VC,因为它必须先冷启动。 0xC0040705 由于未持有VC所有权或无法获得VC所有权,因此请求的操作失败。 0xC0048401 内存不足。 0xC0048402 尚未实现。 0xC0048403 此版本的控制器不支持该服务。 0xC0048404 在活动系统上不允许进行操作。 0xC0048405 请求的数据不存在。 0xC0048406 该目录不包含完成操作所需的所有数据。 0xC0048407 控制器安全访问限制机制拒绝了操作。 0xC0048408 该资源未由调用方保留。 0xC0048409 客户端指定的参数对此类型的操作无效。 0xC004840A 备份和当前系统之间的控制器ID不匹配。 0xC004840B 密钥ID(即选项,语言等)不匹配。在备份和当前系统之间。 0xC004840C 备份系统和当前系统之间的机械手类型不匹配。 0xC004840D 客户端不允许以本地用户身份登录。 0xC004840F 客户端未以控制器用户身份登录。 0xC0048410 所请求的资源已被调用方保留 0xC0048411 已达到请求资源的最大数量。 0xC0048412 给定用户的请求未激活。 0xC0048413 控制器上的操作/请求超时。 0xC0048414 没有本地用户登录。 0xC0048415 给定用户不允许该操作。 0xC0048416 用于初始化帮助程序的URL不能解析为有效的对象。 0xC0048417 数据量太大,无法满足请求。 0xC0048418 控制器忙。稍后再试。 0xC0048419 该请求被拒绝。 0xC004841A 请求的资源由其他人拥有。 0xC004841B 请求的功能已禁用。 0xC004841C 当前操作模式下不允许该操作。例如,可能不允许远程用户在手动模式下执行操作。 0xC004841D 用户没有该操作所需的主控权。 0xC004841E 正在进行备份时,不允许执行该操作。 0xC004841F 任务处于同步状态时,不允许执行操作。 0xC0048420 当任务选择面板中的任务处于非活动状态时,不允许进行该操作。 0xC0048421 备份和当前系统之间的控制器ID不匹配。 0xC0048422 备份和当前之间的控制器ID不匹配。 0xC0048423 无效的客户ID。 0xC0049000 找不到RAPID符号。 0xC0049001 给定的源位置对该操作是非法的。 0xC0049002 T给定的文件未被识别为程序文件,例如XML语义可能不正确。 0xC0049003 模块名称不明确。 0xC0049004 未设置RAPID程序名称。 0xC0049005 模块被读取保护。 0xC0049006 模块被写保护。 0xC0049007 在当前执行状态下操作是非法的。 0xC0049008 在当前任务状态下操作是非法的。 0xC0049009 机械手不在路径上,无法重新启动。重新获得或清除路径。 0xC004900A 在当前执行级别上操作是非法的。 0xC004900B 在不破坏当前执行上下文的情况下无法执行操作。 0xC004900C RAPID堆内存已满。 0xC004900D 由于语法错误,不允许执行操作。 0xC004900E 由于语义错误,不允许进行操作。 0xC004900F 常规不是合法的切入点。可能的原因是:例程是一个函数,或者例程具有参数。 0xC0049010 非法将PCP移至指定位置。 0xC0049011 超过了抢夺目标的最大数量。 0xC0049012 无法修改对象。可能的原因是:对象是变量,对象是参数,对象是数组。 0xC0049013 位移激活时不允许运行。 0xC0049014 机械手不在路径上,无法重新启动。重新获得路径。不允许清除。 0xC0049015 先前计划的路径仍然存在。选择消耗路径(这意味着初始移动可能在意外的方向上),或者选择清除路径并直接移动到下一个目标。 0xC004A000 常规文件处理错误。 0xC004A001 设备已满。 0xC004A002 磁盘错误。更换磁盘,然后重试。 0xC004A003 设备未准备好。 0xC004A004 无效的路径。 0xC004A005 不是有效的设备。 0xC004A006 无法创建目录。 0xC004A007 该目录不存在。 0xC004A008 该目录已存在。 0xC004A009 该目录包含数据。 0xC004A00B 无法创建文件。 0xC004A00C 找不到文件或无法打开文件进行读取。 0xC004A200 禁用

故障排除 概述 如果您的PC SDK应用程序遇到问题,请在联系ABB支持之前执行以下步骤。

Action

1 检查您的问题是否在下一部分的清单中。 2 特定PC SDK版本的发行说明中提供了许多问题的答案。 该文档可在RobotWare DVD和软件下载站点上找到。 3 通过调试代码来查明问题,以便提供准确的问题描述。 4 请访问ABB RobotStudio社区的用户论坛,其中包括一个专门讨论PC SDK主题并进行聊天的论坛。

检查清单 无法连接到控制器?确保控制器上的系统具有RobotWare选件PC接口。这适用于虚拟控制器和实际控制器。

问题是GUI挂起吗?确保由于机器人控制器事件而在修改用户界面时使用Invoke。有关更多信息,请参见冲突和调用方法中的GUI和控制器事件线程。

问题是否与netscan有关?如果NetworkScanner.Scan在netscan期间未找到机械手控制器,则应尝试增加允许的扫描时间。如应用程序配置文件中所述,增加app.config文件中的网络扫描程序延迟时间,或直接在以下代码中添加时间:NetworkScanner aScanner = new NetworkScanner(); aScanner.Scan(); System.Threading.Thread.Sleep(4000); aScanner.Scan();

尝试对机器人控制器进行读取操作时,您是否获得“无效的客户端ID”?如果是这样,则原因可能是您忘记了登录到控制器。例如,要写入RAPID数据或配置数据库,您还需要掌握权限。有关更多信息,请参见登录和注销以及管理权。

如果使用PC SDK的早期版本(5.10之前的版本),可能会遇到与许可证验证有关的问题?如果收到运行时错误“无法为ABB.Robotics.Controllers.Licenses.PCSdk类型授予有效许可证。有关更多信息,请与组件制造商联系。“在访问NetworkScanner和Controller类时,需要将licx文件添加到项目中。有关更多信息,请参见Licenses.licx。

重要的支持信息 如果无法解决问题,请在与ABB支持人员联系时确保以下信息可用:

问题的书面说明。

应用程序源代码。

系统错误日志。

系统的备份。

解决方法的说明(如果存在)。

部署PC SDK应用程序 Overview Introduction 准备好应用程序后,必须将其部署到客户的PC上。 本章提供有关PC SDK安装中包含的部署功能的信息。      注意

托管应用程序的PC上不需要安装PC SDK或PC SDK许可证。 此外,从PC SDK 5.10开始,您无需按照许可证验证中的说明将许可证密钥添加到项目中-仅适用于PC SDK 5.10之前的版本,因为部署的PC应用程序在执行时不再执行许可证验证。

部署设施 在C:\ Program Files \ ABB Industrial IT \ Robotics IT \ SDK \ PC SDK 5.xx的可重新分发文件夹中,有一些文件可用于部署PC SDK应用程序:

ABBControllerAPI.msm

ABB工业机器人通讯Runtime.msi

这两个软件包包括PC SDK应用程序除.NET 2.0以外的所有依赖项。

ABBControllerAPI.msm 没有其引用的PC SDK程序集,PC SDK应用程序将无法执行。 为了方便起见,ABBControllerAPI合并模块包含PC SDK程序集。 将其添加到您的安装程序中,以将它们安装在全局程序集缓存(GAC)中。

GAC随.NET运行时自动安装。 它使PC可以在众多应用程序中共享程序集。 如果客户的PC具有与用于创建应用程序的PS SDK相同版本的RobotStudio Online,则您的应用程序所需的PC SDK dll应该已经在GAC中。

注意

如果要创建msm文件的msi文件(或setup.exe),则可以在Visual Studio设置项目中包括ABBControllerAPI.msm文件。     注意

以前,ABBControllerAPI.msm仅与InstallShield一起使用。 现在已解决此问题。

ABB工业机器人通讯Runtime.msi 要将PC SDK应用程序连接到控制器,需要RobotStudio或Robot Communications Runtime。 如果未在承载应用程序的PC上安装RobotStudio,则需要在安装中包含Robot Communications Runtime。 ABB工业机器人通讯Runtime.msi可作为单独的安装进行重新分配。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有