5 Using the FlexPendant SDK. ABB RobotWare 5.0
Robot Application Builder (RAB) is a software tool, which enables ABB programmers to develop customized operator interfaces for the IRC5 robot controller. Robot Application Builder is fully integrated with Microsoft Visual Studio, which means that a .NET programmer will recognize wizards for project setup, tools for visual design support, and debug etc.
Advertisement
Advertisement
5 Using the FlexPendant SDK
5.1.1. About this chapter
5 Using the FlexPendant SDK
5.1 Introduction
5.1.1. About this chapter
Overview
This chapter gives detailed information on how to use the FlexPendant SDK.
These topics are covered:
•
How to take advantage of some system features that support the use of customized screens.
• How to utilize the integrated Visual Studio wizard to set up a FlexPendant project.
•
How to add the FlexPendant SDK GUI controls to the Visual Studio Toolbox.
• How to build the user interface using the integrated design support.
•
How to program FlexPendant SDK GUI controls.
• How to launch other applications from your application.
•
How to implement controller functionality using CAPI.
The design support in Visual Studio enables you to visually lay out the application, reducing the need to write code. This speeds up development and gives you a more precise control of the appearance of your FP screens.
Using the FlexPendant SDK it is possible to launch several of the standard FlexPendant applications from your application, which is often a very handy alternative to handling complicated procedures on your own, such as reading and writing RAPID data for example.
The Controller API (CAPI) is at the core of the FlexPendant SDK. It is used to access the robot controller, which the FlexPendant is attached to. First there is information about how this public API is organized. Then each domain of CAPI is dealt with separately. There are code samples in C# and VB throughout the chapter.
3HAC028083-001 Revision: D 77
5 Using the FlexPendant SDK
5.1.2. System features supporting the use of customized screens
5.1.2. System features supporting the use of customized screens
Flexible user interfaces
The FlexPendant can be adapted to end-users' specific needs in many different ways. It can be operated in 14 different languages, including Asian character-based languages such as
Japanese and Chinese. Left-handed operators can adapt the device from its default setting by simply rotating the display through 180 degrees. Four of the eight hard keys are programmable, i.e. their function can be assigned by the end-user.
Customized FlexPendant screens, tailored to end-users’ needs is yet another way of rendering the flexible solutions required by many customers. To support the use of customized screens there are a couple of features that you may want to tell the end-users of your application about.
Configure the FlexPendant
Using the FlexPendant configuration facilities (Control Panel - FlexPendant) it is possible to configure the FlexPendant to allow RAPID execution in manual mode from an FP SDK view.
You can also make the FlexPendant automatically display an SDK view at operating mode change.
Additional Test View
Set the FlexPendant configuration property Additional Test View if you want to be able to start
RAPID execution in manual mode with a custom application as the active view.
78
6.1.0_1
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.1.2. System features supporting the use of customized screens
Continued
View On Operating Mode Change
Set the FlexPendant configuration property View On Operating Mode Change if you want the custom application to become active when the controller operating mode is switched to auto, manual or manual full speed.
6.1.0_2
Use RAPID instruction to launch RAB application
The RAPID instruction
UIShow
(User Interface Show) is used to communicate with the user of the robot system via a FlexPendant application. Both RAB applications and standard applications can be launched using this instruction.
Example:
The RAPID code below launches the custom application TpsViewMyApp.
CONST string Name :="TpsViewMyApp.gtpu.dll";CONST string Type
:="ABB.Robotics.SDK.Views.TpsViewMyApp";UIShow Name, Type;
For this to work the robot system must have the RobotWare option FlexPendant Interface.
The assemblies TpsViewMyApp.dll and TpsViewMyApp.gtpu.dll must be located in the
HOME directory of the active robot system. (When the assemblies have been downloaded to the controller the FlexPendant must be restarted in order to load them.)
NOTE!
See the RAPID reference manual for further information about the
UIShow
instruction.
3HAC028083-001 Revision: D 79
5 Using the FlexPendant SDK
5.2.1. Using the project template in Visual Studio
5.2 Setting up a new project
5.2.1. Using the project template in Visual Studio
Overview
It is very simple to set up a new FlexPendant project using the integrated project template that comes with the installation of Robot Application Builder. It will automatically add the most common SDK references to the project and auto-generate some source code for the main application window, in the selected programming language, either C# or Visual Basic.
NOTE!
To add another view to the FlexPendant project, you do not need to start a new project. See
Adding a view to a custom application on page 99
for information about how to do it.
Setup procedure
Follow these steps to create a FlexPendant project:
Step Action
1. On the File menu in Visual Studio, point to New and then click Project.
2. In VS 2005, in the New Project dialog select Visual C# / Smart Device /
FlexPendant or Other Languages/Visual Basic/Smart Device/FlexPendant. In VS
2008, select Visual C# / FlexPendant or Other Languages/Visual Basic/FlexPen-
dant).
80
6.1.1_1
NOTE!
If you have several RAB installations on your PC, there will be several templates to choose from. Make sure you select the template that match the RobotWare version that your application should target.
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.2.1. Using the project template in Visual Studio
Continued
Step Action
3. Enter the name of the application in the Name field and where you want it to be stored in the Location field. Click OK.
NOTE!
The name has to start by “TpsView” . If you forget it an error will be generated by the ABB verification tool when the project is built.
4. The FlexPendant SDK Project Wizard is now launched. For information about how
to configure the application using this wizard see
FlexPendant TpsView attribute on page 54
. When you are ready click OK.
5. You need to set up the design support for the FlexPendant GUI controls before
starting programming. How this is done is detailed in
FlexPendant controls on page 83
.
NOTE!
If the SDK references seem to be missing in your FlexPendant project, see the following section for instructions about how to solve the problem.
Add any missing references
The SDK references needed by the FlexPendant project are added automatically when the
Project wizard is completed. However, there is a possibility that Visual Studio cannot provide the path to these dlls. If this is the case you should add the references path manually. Follow these steps:
Step Action
1. Look at the Solution Explorer of Visual Studio. If you have a C# project expand the
References node. Warning triangles mean that the path to the referenced dlls is missing.
3HAC028083-001 Revision: D
6.1.1_2
For a VB project the Solution Explorer looks the same, except that there is no
References node.
Continues on next page
81
5 Using the FlexPendant SDK
5.2.1. Using the project template in Visual Studio
Continued
Step Action
2. C#: Select the project icon, right-click and select Properties. Click the Reference
Paths tab and add the path to the SDK assemblies.
VB: Select the project icon, right-click and select Properties. Click the References tab. If the path to the SDK references is missing add it by browsing to the directory where they are located.
NOTE!
The default path is C:\Program Files\ABB Industrial IT\Robotics IT\Robot Application
Builder 5.xx\FlexPendant SDK \bin.
3. Save the project. You will notice that any warning triangles in the Solution Explorer
References node will disappear.
82 3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.2.2. Setting up design support for FlexPendant controls
5.2.2. Setting up design support for FlexPendant controls
Overview
This section describes how to make the FlexPendant GUI controls accessible in Visual
Studio.
Procedure
Follow these steps to add the FlexPendant controls to the Visual Studio Toolbox:
Step Action
1. On the View menu, select Toolbox.
2. Right click in the Toolbox area and select Add Tab.
3. Name the new toolbox tab, e.g. FlexPendant Controls.
4. Right click in the area of the new tab and select Choose Items.
5. In the Choose Toolbox Items dialog, browse to the directory where the
FlexPendant SDK assemblies are located and import the following assemblies:
• ABB.Robotics.Tps.Windows.Forms.dll
• ABB.Robotics.GTPU.Windows.Forms.dll
• ABB.Robotics.DataBinding.dll
The default location is C:\Program Files\ABB Industrial IT\Robotics IT\Robot
Application Builder\FlexPendant SDK 5.xx\bin.
6. In the Solution Explorer right-click view.cs (view.vb if you have a VB project) and select View Designer if you are not already in design mode.
As you see, the FlexPendant specific controls are now accessible in the Toolbox.
Introduction to visual design support on page 84
use them.
NOTE!
The way you use the Visual Studio Designer to implement FlexPendant controls is very similar to implementing ordinary .NET controls. In this manual useful information which may not be obvious for all users is provided. But oftentimes, it is the general Visual Studio
Help that will answer any questions you may have about control properties and the like.
3HAC028083-001 Revision: D 83
5 Using the FlexPendant SDK
5.3.1. Introduction to visual design support
5.3 Building the user interface
5.3.1. Introduction to visual design support
What is visual design support?
Design Support for Compact Framework User Controls was a new feature of Visual Studio
2005. It enabled design support for FlexPendant SDK controls to be included in RAB 5.08.
From RAB 5.08 onwards you visually design the FlexPendant application user interface in the Visual Studio Designer. FlexPendant controls are dragged from the toolbox to the designer area, moved and resized by clicking and dragging. By applying different settings in the Properties window of a control, you refine its appearance and behavior.
To be able to use the visual design support you must add the FlexPendant controls to the
Visual Studio toolbox. How to do this is detailed in
Setting up design support for FlexPendant controls on page 83
NOTE!
Design support for FlexPendant controls has long been on RAB users’ wish list. It is indeed a time-saving feature, as most of the code supporting the graphical user interface is now auto generated.
Why special controls for the FlexPendant?
You may wonder why the standard Microsoft Windows controls have not been considered good enough to be used for the FlexPendant touch screen.
The answer is that some Windows controls may very well be used. Other Windows controls are however not so well suited for the FlexPendant touch screen. To navigate using your finger controls in particular need to be large enough. In some other cases the Windows controls simply do not look very good on the touch screen.
NOTE!
In the FP SDK Reference, click the Contents tab and the
ABB.Robotics.Tps.Windows.Forms node to get an overview and a short description of all
ABB controls you may use to create the user interface of a FlexPendant application.
TIP!
How to program these ABB controls is very similar to the equivalent Windows controls. If you need code examples the best source of information is usually MSDN. You may try http:/
/msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/ frlrfsystemwindowsformslistviewclasstopic.asp, for example, to find out how to program a
ListView
.
Illustration
84
The figure below shows the Visual Studio Toolbox with all of the FlexPendant controls to the left. In the Designer area to the right, a FlexPendant application is being developed. Part of the container control, along with a number of ABB and standard Windows controls can be
Continues on next page
3HAC028083-001 Revision: D
seen.
5 Using the FlexPendant SDK
5.3.1. Introduction to visual design support
Continued
6.3.1_1
The following features are worth noting:
•
A Windows PictureBox control is used as the container of a photo.
• The FlexPendant button has a property called BackgroundImage, used to display an image. The ABB image library located in the Resources folder, which comes with the installation of Robot Application Builder, has numerous icons, which can be used by custom applications. You can of course also use photos and icons of your own.
•
Some of the ABB controls, such as the SignalBindingSource, have no graphical representation in design-time. As you see in the figure, they are placed in the components pane under the main form. Code is of course generated, just like for the controls that you see on the form.
• Usually a mix of Windows and ABB controls are used for a FlexPendant SDK application. For example, as there is no ABB RadioButton or CheckBox the equivalent Windows controls are used. In the figure, the standard Windows CheckBox is used.
3HAC028083-001 Revision: D
Continues on next page
85
5 Using the FlexPendant SDK
5.3.1. Introduction to visual design support
Continued
CAUTION!
Do not forget about the limited amount of memory available for custom applications when adding images or photos! See
Technical overview of the FlexPendant device on page 182
.
CAUTION!
Auto generated code for controls is located in the method InitializeComponent
. You should not tamper with the code inside this method. Any modifications or additions to auto generated code is usually best located in the constructor, after the call to
InitializeComponent.
Hands on - Hello world
Are you ready to program and test your first FlexPendant application? If you have not created a FlexPendant project and added the FlexPendant controls to the Visual Studio Toolbox you
Using the project template in Visual Studio on page 80
and
Setting up design support for FlexPendant controls on page 83
.
Follow these steps to create and test a simple custom application:
Step Action
1. Drag a FlexPendant button from the Toolbox to the Designer.
2. Double-click the button in the Designer, this opens the code editor.
3. As you see an event handler for the click event has been created. Add the code to launch the Hello World message in it:
{ private void button1_Click(object sender, EventArgs e)
GTPUMessageBox.Show(this.Parent
, null
, "Hello world!"
, "Application Message"
, System.Windows.Forms.MessageBoxIcon.Asterisk
, System.Windows.Forms.MessageBoxButtons.OK);
}
An alternative way of adding an event handler is shown in the next step.
NOTE!
The above code sample has no exception handling. A FlexPendant application to be used in industry must have exception handling in all event handlers. The FlexPendant has only ONE GUI thread, which all applications running on the FlexPendant share.
If your application breaks the only GUI thread, all of the applications will die and the
FlexPendant must be restarted manually. See
out more about this important issue.
86
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.3.1. Introduction to visual design support
Continued
Step Action
4. Bring up the Properties window for the button by right clicking it in the Designer and selecting Properties. Click the events button (yellow flashing lightening) to see the events available for the ABB button. As shown by the figure, you have already connected an event handler to the click event.
6.3.1_1B
NOTE!
It is the default event of the control that you get when you double-click it in the
Designer. To add an event handler for another button event, bring up the Properties window and double-click the event you want to generate a handler for, e.g. a
FontChanged
event handler. You will enter the code editor, the cursor inside the generated event handler.
5. On the Build menu, click Build Solution and check that you did not get any compilation errors.
6. To test the application you need to deploy it to a robot system. If there is no robot system available, you must create a robot system by using the System Builder of
RobotStudio.
7. Copy the assembly (*.dll) and the proxy assembly (*.gtpu.dll) from the bin\Debug (or bin\Release) directory of your Visual Studio project to the HOME directory created by
RobotStudio when your robot system was created.
Example showing default paths for copy/paste:
C:\Data\Visual Studio 2005\Projects\TpsViewMyApp\TpsViewMyApp\bin\Debug\
C:\Systems\sys1_508\HOME
Note! If you have already started the virtual FlexPendant you need to close it before pasting the dlls.
8. Start the virtual FlexPendant.
9. On the ABB menu, find your application and open it.
3HAC028083-001 Revision: D
Continues on next page
87
5 Using the FlexPendant SDK
5.3.1. Introduction to visual design support
Continued
Step Action
10. Click the button. The Hello World message will be displayed.
88
6.3.1_2
NOTE!
below if you wish to know how to implement the
additional features shown above: application title, button background image, command bar with a menu item and an event handler to launch a standard view.
TIP!
When using the Virtual FlexPendant for test and debug you can automate the copy/paste procedure described in step seven above. This is how you do it:
1. Right click the project icon in the Solution Explorer and select Properties.
2. For a C# project, select the Build Events tab. (For a VB project click the Compile tab and then the Build Events button.)
3. Press the Edit Post-build button and add two commands which will copy the produced dlls to the directory of the robot system to run. Example:
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.3.1. Introduction to visual design support
Continued
copy "$(TargetDir)$(TargetName).dll" "C:\Systems\sys1" copy "$(TargetDir)$(TargetName).gtpu.dll" "C:\Systems\sys1"
Note! Do not remove the default post build command lines, which create the assembly proxy
(*gtpu.dll).
Hands on - step 2
This section details how to program the remaining features of the Hello World application shown in step nine above: application title, button background image, command bar with a menu item. You will also learn how to implement an event handler for the Launch View command.
When you create a FlexPendant project you choose Empty or Form in the FlexPendant
to understand the difference between
them. In our example Form is selected as the container control.
Step Action
1. If you selected Empty for your project you can change it to Form by exchanging
TpsControl with
TpsForm
directly in the source code, like this:
C#: public class TpsViewIRC5App14 : TpsForm, ITpsViewSetup,
ITpsViewActivation
VB:
Public Class TpsViewIRC5App14 Inherits TpsForm '(was
TpsControl before) Implements ITpsViewSetup,
ITpsViewActivation
Notice that the Designer now shows the title bar on top of the container control.
2. Right-click somewhere in the middle of the container control and select Properties.
3. Enter “This is my Hello World application” at the Text property. See the tip of
if the Text property is not available.
4. Still using the TpsForm Properties window, expand the MainMenu property node.
5. Click the MenuItems property and the browse button which appears once the property is selected.
3HAC028083-001 Revision: D
Continues on next page
89
5 Using the FlexPendant SDK
5.3.1. Introduction to visual design support
Continued
Step Action
6. In the MenuItem Collection Editor, which is now launched, click the Add button.
Then enter “Launch View” at the Text property. Click OK.
6.3.1_4
NOTE!
The added menuItem has its own MenuItems property. You use it if the “Launch
View” command is to present a menu instead of working as a button on the command
bar. How this can be done is further detailed in
How to add menu items on page 101
90
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.3.1. Introduction to visual design support
Continued
Step Action
7. Add an event handler with code that will launch the standard Jogging view when the
Launch View button is pressed.
Adding event handlers is done differently in Visual Studio depending on which programming language you are using.
For C#:
In the constructor, after the call to
InitializeComponent
, add a subscription to the click event of the “Launch View” command. Write: menuItem1.Click += then TAB twice. As you will notice, Visual Studio intellisense auto generates an event handler, and you only need to write the code for launching the Jogging view: this._launchService.LaunchView(FpStandardView.Jogging,null,fa lse,out this._cookieJog)
For VB:
Add an event handler using the drop down boxes above the Visual Studio Code
Viewer. Find and select MenuItem1 in the left drop down box and the Click event in the right drop down box. The event handler is now auto generated for you, and the only thing you need to do is to write the code for launching the Jogging view (see VB code in
Launching standard views on page 129
).
NOTE!
There is no possibility to attach an event handler in the properties window, like you do for a
Button
for example.
8. Declare the _launchService and the _cookieJog objects: private ABB.Robotics.Tps.Taf.ITpsViewLaunchServices
_launchService;private object _cookieJog;
9. Retrieve the
_launchService
object in the
Install
method of your class:
6.3.1_5
ITpsViewSetup Install on page 128
10. In the designer, open the Properties window of the button.
11. Enter “Press Me” at the Text property.
12. Select the BackgroundImage property and browse to the Resources folder of the
RAB installation and import “IRB140.gif”.
(Default path: C:\Program Files\ABB Industrial IT\Robotics IT\Robot Application
Builder\FlexPendant SDK 5.08\Resources)
13. Build, deploy and start the application, that is repeat step five to eight in
.
3HAC028083-001 Revision: D
Continues on next page
91
5 Using the FlexPendant SDK
5.3.1. Introduction to visual design support
Continued
Step Action
14. Press the Launch VIew command.
The Jogging view should open up and get focus.
TIP!
Using launch service on page 128
Using standard dialogs to modify data on page
if you want to know more about the possibilities to use already existing views for your application
Visual design and user experience
There is another definition of the term Visual design, which is not in the scope of this manual.
It has to do with how the design of the software user interface affects user experience. This is nonetheless an important topic for a FlexPendant application developer. Knowing what makes a user interface intuitive and easy to use is essential, as this is exactly what is expected from a custom operator interface.
TIP!
A FlexPendant style guide comes with the installation of RAB. It will help you to present application functionality in an intuitive way, teaching best practices of visual design and user experience from the FlexPendant perspective. It is a preliminary draft, but still very useful.
You may also want to study the Microsoft standard for visual design at: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwue/html/ch14a.asp
92 3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.3.2. GUI controls and memory management
5.3.2. GUI controls and memory management
Overview
All of the FlexPendant SDK controls belong to the
ABB.Robotics.Tps.Windows.Forms
namespace. This namespace thus includes well over 40 classes and subclasses used to develop the user interface of a FlexPendant application.
ABB.Robotics.Tps.Windows.Forms.TpsControl
is the base type of all FlexPendant
SDK controls.
TpsControl
in turn extends
System.Windows.Forms.UserControl
TpsControl
may be used as a container control of a FlexPendant view. It also has the default implementation of
Dispose
, which is called in order to free allocated memory for a control which should no longer be used.
You may wonder why this is necessary, as the .NET framework has a garbage collector, which should release the developer of the duty to free allocated memory. The answer is the garbage collector does not always reclaim memory which is no longer used. Therefore, if you program an application meant to execute around the clock on a device with limited memory, you are still responsible for freeing memory which is no longer used. Neglecting to do so will result in permanent memory leaks.
How to avoid memory leaks
Look at this figure showing a number of controls (both ABB and Microsoft) and learn the basics about memory management for GUI controls. It is not so complicated, the most important thing is not to forget that cleaning up is your responsibility!
6.3.2_1
3HAC028083-001 Revision: D
Continues on next page
93
5 Using the FlexPendant SDK
5.3.2. GUI controls and memory management
Continued
Learn and apply these the general rules for memory management of GUI controls.
• Controls with a graphical representation, e.g the ABB
Numpad
,
TabControl
,
GroupBox
,
TpsLabel
,
ListView
and the Microsoft
PicureBox
and
DataGrid
in the figure, are automatically added to the controls collection in
InitializeComponent. It may look like this: this.Controls.Add(this.numPad1);
•
If the figure above represents the first view of your application, controls with graphical representation will be disposed of by the base class of your view class when your application is shut down and the
Dispose
method is called by TAF. This happens when the following statement in your
Dispose
method is executed: base.Dispose(disposing);
• If, however, it represents a secondary view of your application (which is actually the case here, as you can tell from the close button on the command bar), you must call its
Dispose
method from the first view when it is closed. Its base class will then remove all controls that are part of its controls collection, like in the previous case.
•
GUI controls that have no graphical representation, but are located in the Components
pane under the form, e.g.
GTPUSaveFileDialog
,
RapidDataBindingSource
,
AlphaPad
etcetera, are NOT added to the controls collection by default. These are the ones that you need to be especially careful to remove, as no garbage collector will ever gather them. If you forget to explicitly call
Dispose
on such controls you will have caused a permanent memory leak. Carefully study the code example in the next section.
NOTE!
Microsoft and ABB controls behave in the same way. The Microsoft
ImageList
for example, which is commonly used in FlexPendant applications, has no graphical representation and must thus be explicitly removed by the application programmer.
Coding the Dispose method
The code example below shows how the
Dispose
method of the view shown in the figure above can be coded. All controls located in the components pane in the Designer must be explicitly removed by the programmer. Controls with a graphical representation will be removed when
Dispose
of the base class is executed. protected override void Dispose(bool disposing)
{ if (!IsDisposed)
{ try
{ if (disposing)
{
//Removes SaveFile dialog if(this.gtpuSaveFileDialog1 != null)
{ this.gtpuSaveFileDialog1.Dispose(); this.gtpuSaveFileDialog1 = null;
94
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.3.2. GUI controls and memory management
Continued
}
}
}
//Removes RapidDataBindingSource if(this.rapidDataBindingSource1 != null)
{ this.rapidDataBindingSource1.Dispose(); this.rapidDataBindingSource1 = null
}
//Removes Alphapad if(this.alphaPad1 != null)
{ this.alphaPad1.Dispose(); this.alphaPad1 = null
}
//Removes FolderBrowserDialog if(this.gtpuFolderBrowserDialog1 != null)
{ this.gtpuFolderBrowserDialog1.Dispose(); this.gtpuFolderBrowserDialog1 = null
}
//Removes ImageList if(this.imageList1 != null)
{ this.imageList1.Dispose(); this.imageList1 = null
}
}
} finally
{
//Removes all controls added to the controls collection
base.Dispose(disposing);
}
Finally, as this is a secondary view, we should call its
Dispose
method from the first view when it is closed down.
//This code is executed by the first view when the secondary view is closed void form2_Closed(object sender, EventArgs e)
{ if(form2 != null)
{ form2.Dispose(); form2 = null;
}
}
3HAC028083-001 Revision: D
Continues on next page
95
5 Using the FlexPendant SDK
5.3.2. GUI controls and memory management
Continued
CAUTION!
If you forget to call
Dispose
on controls that are not part of the control collection of the class there will be memory leaks. This may cause the FlexPendant to run completely out of memory and crash. Usually, this will not happen when you try out the functionality of your application, but when it is executed and used continuously during production. To verify that a GUI control is really disposed of, you may set up a subscription to its Disposed event for example, and verify that it is triggered when you close down the view.
CAUTION!
All objects accessing robot controller services, i.e. unmanaged resources, must also be
removed by the application programmer. See
for further information.
Freeing allocated memory for a GUI control
You are recommended to remove a GUI control in the
Dispose
method of the class that created it. If the control belongs to the first view of your application, it will be disposed of when TAF calls
Dispose
at application shut down. If it belongs to a secondary view, you are responsible for disposing of the secondary view and its controls.
C#: if (this.controlX != null)
{
controlX.Dispose();
controlX = null;
} base.Dispose(disposing);
VB:
If disposing Then
If Not controlX Is Nothing Then controlX.Dispose() controlX = Nothing
End If
End If
MyBase.Dispose(disposing)
NOTE!
When the last statement in the code example above is executed the base class will call
Dispose
on all controls added to the controls collection in
InitializeComponent
. This means that you do not need to call
Dispose
on such controls.
96 3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.3.3. Container style
5.3.3. Container style
Overview
The container control of a FlexPendant application is 640x390 pixels, which is the exact size of the FlexPendant screen dedicated for a custom view. This section details the two different styles that can be used for a FlexPendant view: Empty and Form.
You select which one to use in the Style area of the FlexPendant SDK Project Wizard. To the left in the wizard, a preview helps you see the difference between the two styles.
6.2.2_1
Here Form is selected. The preview illustration shows a
TpsForm
. It has a
CommandBar
at the bottom and a
TpsCtrlTitleBar
at the top.
NOTE!
When adding a new view to an existing FlexPendant project, you choose which control to use in the Add New Item dialog box. See
Adding a view to a custom application on page 99
for information on how to add a new view to an existing project.
Empty or Form?
Empty
Your choice in the wizard determines the type that your view class will inherit. If you change your mind about this, it is easy to make the change directly in the auto generated code.
This is a plain
TpsControl
. It has neither a
CommandBar
, nor a
TpsCtrlTitleBar
.
The code definition of the class will look like this:
VB:
Public Class TpsViewMyApp Inherits TpsControl Implements
ITpsViewSetup, ITpsViewActivation
3HAC028083-001 Revision: D
Continues on next page
97
5 Using the FlexPendant SDK
5.3.3. Container style
Continued
Form
This is a
TpsForm
, which is a specialized
TpsControl
.
The code definition of the class will look like this:
VB:
Public Class TpsViewMyApp Inherits TpsForm Implements
ITpsViewSetup, ITpsViewActivation
98
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.3.3. Container style
Continued
NOTE!
Often Empty is chosen as the first view of an FP SDK application. For any secondary view, which is to be opened from the first one, Form is the recommended container control.
NOTE!
When selecting Form you might wonder why the command bar is not visible in the designer.
The answer is that it remains invisible until a
MenuItem
has been added to it. This is done in the Properties window of the
TpsForm
, by applying the property MainMenu.
TIP!
If you select the
TitlePanel
or the
CommandBar
of a
TpsForm
you will see that the
Properties window is disabled. If you want to change the text of the title panel, or add menu items to the command bar, for example, you must select
TpsForm
by clicking somewhere in the middle and then modify its Text or MainMenu property.
How to build the command bar
The command bar is either ready-made, as for
TpsForm
, or used as a separate control available from the toolbox. If the command bar is ready-made, the design of it is done by modifying the MainMenu property of
TpsForm
. If used as a separate control, you design it by modifying its own properties. Apart from this, there is no difference in how you control the design.
An important thing to remember is that you have to manually add the code controlling what will happen when the user presses a menu item, as there are no event properties available in its Properties window.
for further information on how to implement the control and
its event handlers.
CAUTION!
The command bar of the first view of a custom application should not have a Close button.
The reason is that all custom application must be closed down by TAF, which happens when the user presses the close [ x ] button in the upper right corner of the FlexPendant display.
(See
Understanding FlexPendant application life cycle on page 52
for further information on TAF.)
Adding a view to a custom application
To add another view to the FlexPendant project, you do not need to start a new project. This is how to proceed:
Step Action
1
2
Right-click the project node in the Solution Explorer, point to Add and select New
Item.
Select one of the FlexPendant container controls available in the dialog box.
Normally it will be a Form.
Note! If you select Empty the code you write to open it from the first view is a bit different than if you are using Form as a secondary view.
3HAC028083-001 Revision: D
Continues on next page
99
5 Using the FlexPendant SDK
5.3.3. Container style
Continued
This way all of your views make up a single dll, which is convenient. Most of the time there is no point in dividing the application into several dlls.
Launching the view
The code for launching the secondary view is simple. It may look like this:
//declare the secondary view as a private member private View2 _view2;
//create the view and add subscription to its closed event, then launch view private void button1_Click(object sender, EventArgs e)
{ this._view2 = new View2(); this._view2.Closed += new EventHandler(view2_Closed); this._view2.ShowMe(this);
}
//dispose of the view when it has been closed void view2_Closed(object sender, EventArgs e)
{ this._view2.Closed -= new EventHandler(view2_Closed); this._view2.Dispose(); this._view2 = null;
}
NOTE!
Make sure that there is a natural way for the user to get back to the preceding view. The most intuitive way of doing this is to press a Close button or an OK or Cancel button on the command bar. If the secondary view is a
TpsForm
, this event handler closes it: void menuItem1_Click(object sender, EventArgs e)
{
this.CloseMe();
}
NOTE!
If you are using Empty as a secondary container control the code you write to launch it is: this._view2.Show();
It must be added to the first view’s control collection before it can be shown, just like an ordinary .NET control.
100 3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.3.4. Command bar
5.3.4. Command bar
Overview
For the end-user the command bar is a central FlexPendant control and an important means
of interacting with the system. As described in
How to build the command bar on page 99
it can be ready-made or added to the container control from the VS Toolbox.
How to add menu items
If you use the
Form
container a command bar is built-in, but not visible until you add a
MenuItem collection to the MainMenu property of
TpsForm
. How to do this is shown in step
If you use Empty as container the command bar needs to be added from the Toolbox. In this case too, the commands are added as a collection of menu items.
6.3.4_1
The command bar in this figure has a collection of three menu items: Launch View, Close
View and Close. Moreover, the Launch View menu item has its own collection of menu items:
Rapid Data, Jogging and Backup Restore.
In the figure, as shown by the task bar, the Backup Restore view has been opened. It has been done by clicking the Backup Restore menu item. The user has then returned to the Hello
World application by using the task bar. If Close View is now pressed, the Backup Restore view will close down. The next section shows how event handlers for this command bar can be implemented.
3HAC028083-001 Revision: D
Continues on next page
101
5 Using the FlexPendant SDK
5.3.4. Command bar
Continued
How to add menu item event handling
Subscriptions to menu item events and event handling cannot be added using the design support, but have to be implemented by hand in the source file. The code example below shows how the command bar in the figure above can be implemented.
102
6.3.4_2
NOTE!
To launch a standard view the
ITpsViewLaunchServices
object, which can be saved by the
TpsView
class in its
Install
Using launch service on page 128
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.3.5. FlexPendant fonts
5.3.5. FlexPendant fonts
Overview
On the FlexPendant,
TpsFont
is used instead of standard Windows fonts. By using TpsFont you save limited device memory, as static references instead of new font instances will be used.
TpsFont
Tahoma
is the default font of the FlexPendant. It is also the font usually used internally by
TpsFont
. A number of different font sizes are pre-allocated and can be reused. You are recommended to use TpsFont instead of creating new font instances for both ABB and .NET
UI controls.
NOTE!
To be able to use Chinese or another language with non-western characters, you must use the
FlexPendant font,
TpsFont
, for any UI controls. It internally checks what language is currently active on the FlexPendant and uses the correct font for that language.
NOTE!
If you use other fonts than available on the FlexPendant, i.e. Tahoma and Courier New, the application will use Tahoma instead of the intended one.
3HAC028083-001 Revision: D 103
5 Using the FlexPendant SDK
5.3.6. The use of icons
5.3.6. The use of icons
Overview
It is easy to display icons, images and photos on the FlexPendant touch screen. Utilizing this possibility is recommended, as many people find it easier to read pictures than text. Intuitive pictures can also be widely understood, which is a real advantage in a multinational setting.
NOTE!
The operating system of the first generation FlexPendant device (SX TPU 1) does not support images of more than 256 colors.
CAUTION!
Be aware of the limited memory resources of the FlexPendant device. Do not use larger
images than necessary. Also see
How large can a custom application be? on page 182
FlexPendant controls with images
Several FlexPendant controls support images, which are imported as bmp, jpg, gif or ico files when an Image, Icon or BackgroundImage property is set. These are some controls to be used with pictures:
•
MenuItem
•
Button
•
TpsCtrlTitlePanel
•
TabPage
•
ListViewItem
•
TpsForm
•
FPRapidData
,
FpToolCalibration
,
FpWorkObjectCalibration
•
GTPUSaveFileDialog
PictureBox and ImageList
There are also some Windows controls that can be used to display images.
Windows.Forms.PictureBox
is one such control. It can display graphics from a bitmap
(.bmp), icon (.ico), JPEG or GIF file. You set the Image property to the preferred image either at design time or at run time.
Windows.Forms.ImageList
can manage a collection of Image objects. The ImageList is typically used by another control, such as the
ListView
or the
TabControl
. You add bitmaps or icons to the
ImageList
, and the other control can choose an image from the
ImageList
index. How to use images for a
TabControl
is detailed in
How to add tab images on page 106
104
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.3.6. The use of icons
Continued
The TpsIcon class
The
TpsIcon
class offers static references to a number of icons used in the standard
FlexPendant applications. You may want to use some of these icons if they suit the application need.
TpsIcon
belongs to the namespace
ABB.Robotics.Tps.Drawing
.
TIP!
In the FP SDK Reference, click the Search tab and search for TpsIcon Members to get a short description of the ABB icons that are available as static properties.
3HAC028083-001 Revision: D 105
5 Using the FlexPendant SDK
5.3.7. TabControl
5.3.7. TabControl
Overview
The
ABB.Robotics.Tps.TabControl is used and implemented much in the same way as a regular
System.Windows.Forms.TabControl
. The possibility to use tab icons, however, is an additional feature of the ABB
TabControl
.
Illustration
The figure below shows a
TabControl
and its Properties window. To add or remove tab pages you click the little arrow in the top right corner of the control or click Add new
TabPage at the bottom of the Properties window.
6.2.4_1
NOTE!
The ABB
TabControl
has no TabPages property. Depending on where in the TabControl you click, you select either the entire
TabControl
or one of the
TabPages
. To view the
Properties window for the T_ROB1
TabPage
in the figure, you would have to click the
T_ROB1 tab and then the T_ROB1 page below the tab.
How to add tab images
This is how you use the ImageList property to add icons to the tabs of the
TabControl
:
2
3
Step Action
1 Drag a
System.Windows.Forms.ImageList
to the Designer area. As you will notice it has no visual representation, but is placed on the components pane below the container control.
Display the Properties window of the ImageList.
Click the property Images and then the browse button, which will appear.
106
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.3.7. TabControl
Continued
Step Action
4 Click Add and import an image. Repeat until you have added the icons your
TabControl needs.
5
6
6.2.4_2
Now display the Properties window of the
TabControl
and select your
ImageList as the ImageList property.
Select one of the tab pages and set the property ImageIndex, which defines which of the images in the
ImageList
is to be used for the tab. Repeat this procedure for all tab pages.
How to add an event handler using the Properties window
It is easy to attach an event handler to a control by using the Properties window. This procedure shows how to make something happen when the user clicks a tab to select another tab page:
Step Action
1 In the Designer, select the
TabControl
and display the Properties window.
3HAC028083-001 Revision: D
Continues on next page
107
5 Using the FlexPendant SDK
5.3.7. TabControl
Continued
Step Action
2 Display the events available for the control by clicking the Events button.
3
4
5
6.3.4_3
Select the SelectedIndexChanged event and double click. A method name is now auto generated for the SelectedIndexChanged event. The code view takes focus, the cursor placed inside the generated event handler.
Add code to make something happen. For now this code will do: this.Text = "TabControl notifies change of tab pages";
This will change the title text of the TpsForm when a tab is clicked.
Test the functionality by building, deploying and starting the application. See step 5-
Hands on - Hello world on page 86
NOTE!
The subscription to the event has been done under the hood, and you do not need to bother about it. If you use C# you will notice that some code adding the subscription has been inserted in the
InitializeComponent
method: this.tabControl1.SelectedIndexChanged += new
System.EventHandler(this.tabControl1_SelectedIndexChanged);
Disposing TabControl
You do not need to explicitly call
Dispose
on the
TabControl
object. The reason is that
InitializeComponent
adds the tab pages to the controls collection of the
TabControl
, and the
TabControl
itself to the control collection of the container class. this.Controls.Add(this.tabControl1);
The
TabControl
is thus removed when the
Dispose
method of your container class calls
Dispose
on its base class like this: base.Dispose(disposing);
108 3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.3.8. Button, TextBox and ComboBox
5.3.8. Button, TextBox and ComboBox
Overview
The FlexPendant button, text box and combo box controls are not very different from the equivalent Windows controls.
Using Button
A common size of a FlexPendant
Button
is 120 * 45 pixels; it can be a lot smaller than its default size. As opposed to a Windows button it can display an image. As pointed out in
you use the property BackgroundImage and browse for the image
to be displayed.
Using TextBox
The
TextBox
control is multiline by default and uses the typical FlexPendant scroll bars as shown in the figure below.
6.2.7_1
Using ComboBox
The
ComboBox
is very similar to the
System.Windows.Forms.ComboBox
, but is visually improved to suit the FlexPendant touch screen. It can be statically populated using the Items property as illustrated by the figure. If you wish to populate it dynamically, you need to write code for it.
6.2.7_2
SelectedIndexChanged
is the most commonly used among the events. It occurs when the user selects another item from the list.
3HAC028083-001 Revision: D 109
5 Using the FlexPendant SDK
5.3.9. AlphaPad
5.3.9. AlphaPad
Overview
The
AlphaPad
control is a virtual keyboard, which enables the user to enter strings. It covers the whole FlexPendant display. The figure shows its appearance in run time.
6.2.10_1
The
AlphaPad
has no graphical representation in design-time. When dragged from the
Toolbox to the Designer it is placed in the components pane, as shown by the figure in the next section. Code is of course generated for it, just like for controls that are visually laid out on the form in design-time.
110
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.3.9. AlphaPad
Continued
Launching the AlphaPad
You need to write some code to launch the virtual keyboard. This is how you do it:
C#: this.alphaPad1.ShowMe(this);
VB:
Me.AlphaPad1.ShowMe(Me)
NOTE!
The code for launching the
AlphaPad
should be executed by an appropriate event handler.
Adding event handlers
The Properties window can be used to program
AlphaPad
event handlers. You double click the event you want to respond to. This takes you to the code editor, the cursor placed inside the auto generated event handler, where you can write code to save user input to a member variable for example: if (alphaPad1.SelectedText != string.Empty)
{
_userInput = alphaPad1.SelectedText;
}
6.2.10_2
Validating the result at the Closing event
The
Closing
event is generated when the OK or Cancel button of the
AlphaPad
is pressed.
You can use this event to validate the string entered by the user. You can set the Cancel property of the event argument to true if you want the AlphaPad to remain open until a valid input value has been entered:
VB:
Private Sub NamePad_Closing(sender As Object, e As
System.ComponentModel.CancelEventArgs) Handles
NamePad.Closing
If NamePad.SelectedText.CompareTo("No Name") = 0 &&
NamePad.DialogResult =
System.Windows.Forms.DialogResult.OK Then e.Cancel = True
Continues on next page
3HAC028083-001 Revision: D 111
5 Using the FlexPendant SDK
5.3.9. AlphaPad
Continued
C#:
End If
End Sub private void namePad_Closing(object sender,
System.ComponentModel.CancelEventArgs e)
{ if ((this.namePad.SelectedText.CompareTo("No Name") == 0) &&
(this.namePad.DialogResult ==
System.Windows.Forms.DialogResult.OK))
{ e.Cancel = true;
}
}
Using the result at the Closed event
The Closed event has to be caught by an event handler, as the object cannot be disposed of until it has been closed. The result may be retrieved in this event handler or in the Closing event handler. First check that OK and not Cancel was pressed, then retrieve user input.
Finally the AlphaPad should be disposed of.VB:
C#:
Private Sub NamePad_Closed(sender As Object, e As EventArgs)
Handles NamePad.Closed
If NamePad.DialogResult = Windows.Forms.DialogResult.OK Then
Me.answer = NamePad.SelectedText
End IfNamePad.Dispose()
End Sub private void namePad_Closed(object sender, EventArgs e)
{ if (this.namePad.DialogResult ==
System.Windows.Forms.DialogResult.OK)
{ this.answer = this.namePad.SelectedText;
} this.alphaPad1.Dispose();
}
112
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.3.9. AlphaPad
Continued
Removing the AlphaPad control
The
AlphaPad
is NOT added to the control collection, and will therefore NOT be disposed of by the base class of its container.
You are responsible for explicitly calling its
Dispose
method when it is no longer used. In the example above, this is done at the
Closed
event. This implies that a new
AlphaPad instance is created the next time its launch event is triggered.
Another way of dealing with this is to let the instance created by the Designer live until its container view is closed. This alternative means destroying it in the
Dispose
method of the container class: this.alphaPad1.Dispose();
CAUTION!
If you forget to call
Dispose
on an AlphaPad control you will have a memory leak. For further information see
GUI controls and memory management on page 93
3HAC028083-001 Revision: D 113
5 Using the FlexPendant SDK
5.3.10. ListView
5.3.10. ListView
Overview
The
ABB.Robotics.Tps.Windows.Forms.ListView
is very similar to a standard .Net
ListView
. The main difference is that its appearance is somewhat adapted to the use of a touch screen, as can be seen in the figure.
You can use the
ListView
control in a variety of ways. Usually you use it to display a list of items with item text and, optionally, an icon to identify the type of item. By using the
CheckBoxes property it is also possible to have a check box appear next to each item in the control, allowing users to check the items they want to perform an action on.
Illustration
The figure shows the Designer. You see two different ABB
ListView
lists, a standard .Net
ImageList
in the components pane under the lists and the Properties window for the
Calibration, HotEdit list.
6.3.10_1
Using properties to control appearance
The first list has CheckBoxes set to true. To have columns displayed View must be set to
Details. The columns are created by selecting Columns and adding any number of columns in the ColumnHeader Collection Editor. Scrollable has been set to true to enable the user to scroll the list to see all items. To have the current number of list items displayed
114
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.3.10. ListView
Continued
ShowNumberOfItems has been set to true. By using Sorting the list items can be alphabetically sorted, in this case in Descending order. The list is statically populated, using the Items property.
The View property of the other list is set to LargeIcon instead of Details. To display icons a standard .Net ImageList is used. You first launch the Properties window for the ImageList and add the images you want to use. At the LargeImageList property of the
ListView
you select the image list, and for each Item you select the ImageIndex to use, as is shown in the
ListViewItem Collection Editor.
Using the Properties window you can also add event handling. The most commonly used event is SelectedIndexChanged, which is triggered when a new list item is selected.
The Properties window can be used to statically populate the list. Usually, however, lists are populated dynamically. In
Getting signals using SignalFilter on page 167
there is a code example, which shows how I/O signals are dynamically displayed in an ABB
ListView
.
ABB specific properties
These properties are specific for the ABB
ListView
:
Property
MultiSelect
Scrollable
SelectionEnabledOver-
Scrollbuttons
ShowNumberOfItems
ShowSelection
Usage
Specifies whether multiple items in the control can be selected. The default is false.
Specifies whether a scroll bar is added to the control when there is not enough room to display all items. The default is true.
Note! The typical FlexPendant scroll bars are used by the first list in the figure above.
Specifies whether a touch inside the scroll region should select an item or scroll the list. The default is false.
Specifies whether the current number of items in the list is displayed. The default is true. Scroll bars should be added to the control to allow the user to see all the items. If the list is not scrollable the default value is false.
Specifies whether selection is shown or not. The default is false.
3HAC028083-001 Revision: D 115
5 Using the FlexPendant SDK
5.3.11. CompactAlphaPad and NumPad
5.3.11. CompactAlphaPad and NumPad
Using CompactAlphaPad
The
CompactAlphaPad
control is used to enable user input. The input can be in the form of capital letters or numbers depending on the property
ActiveCharPanel
, which can be set to
Characters
or
Numeric
. It has a fixed size, big enough for the use of a finger to press its keys. There are properties available to define whether the numerical panel should support numerical operands, special characters, space and comma. All these properties are set to true in the figure:
Using NumPad
6.3.11_1
In order for your application to use the user input, you must connect to a text box, which displays the text or figures entered. This connection has to be coded manually, for example in the constructor, after the call to
InitializeComponent
, e.g.: this.compactAlphaPad1.Target = this.textBox1;
The
NumPad
is very similar to the CompactAlphaPad. You have to create a
Target
to be able to use the input, e.g.: this.numPad1.Target = this.textBox2;
116
6.3.11_2
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.3.12. GTPUMessageBox
5.3.12. GTPUMessageBox
Overview
GTPUMessageBox
is the message box control to be used by FlexPendant applications. You should not use the standard
.NET MessageBox
.
Design issues
The
GTPUMessageBox.Show
arguments include an owner argument, which is the control that displays the
MessageBox
, and a callback, which is a
MessageBoxEventHandler called when the MessageBox is closed.
Except this, it is used in the same way as the regular Windows
MessageBox
. It is used together with the regular Windows
MessageBoxButtons
and
MessageBoxIcon
.
Simple code example
The figure and code below show how to display a simple message on the FlexPendant using the
GTPUMessageBox
.
6.2.6_1
string message = "You did not enter a server name. Cancel this operation?"; string caption = "No Server Name Specified";
GTPUMessageBox.Show(this, null, message, caption,
System.Windows.Forms.MessageBoxIcon.Question,
System.Windows.Forms.MessageBoxButtons.YesNo);
3HAC028083-001 Revision: D
Continues on next page
117
5 Using the FlexPendant SDK
5.3.12. GTPUMessageBox
Continued
NOTE!
Sometimes it can be a bit tricky to get the first argument right. The owner might be this, this.Parent or even this.Parent.Parent
.
Using a callback
The logics in your program determines if there is any need for a callback. In the previous example the callback argument was null
.The message box will just close down after the user has answered the question, no matter if the answer is Yes or No.
If we think about the message, it seems likely however, that something should happen if the user presses No. Let us change the implementation and use a callback for this purpose:
GTPUMessageBox.Show(this, new
MessageBoxEventHandler(OnServerMessageClosed), message, caption, System.Windows.Forms.MessageBoxIcon.Question,
System.Windows.Forms.MessageBoxButtons.YesNo);
//implement callback private void OnServerMessageClosed(object sender,
ABB.Robotics.Tps.Windows.Forms.MessageBoxEventArgs e)
{ if(e.DialogResult == System.Windows.Forms.DialogResult.No)
{
//Use default server...
}
}
If we really do not want to take action depending on how the user responds, it makes more sense to use OK instead of Yes and No as message box buttons, e.g:
GTPUMessageBox.Show(this, null, "You are not allowed to perform this operation, talk to your system administrator if you need access",
"User Authorization System", MessageBoxIcon.Hand,
MessageBoxButtons.OK);
NOTE!
The last example uses a better message box title then the previous ones. The title preferably should tell the user from which part of the system the message originates.
118 3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.3.13. GTPUFileDialog
5.3.13. GTPUFileDialog
Overview
The FlexPendant SDK provides a number of file dialogs used by the end-user to interact with the file system of the robot controller. These controls all inherit the abstract class
GTPUFileDialog
and belong to the namespace
ABB.Robotics.Tps.Windows.Forms.
File dialog types
There are three different types of file dialog controls:
Use...
when you want to...
GTPUOpenFileDialog
GTPUSaveFileDialog
Enable the user to specify a file to be retrieved from the controller file system.
Enable the user to specify a file to be saved to the controller file system.
GTPUFolderBrowserDialog
Enable the user to specify a folder on the controller file system.
NOTE!
The Open/Save/Browse file dialogs represent a convenient way for the user to specify folder and filename for a file operation. You should know, however, that the dialogs themselves do not perform any file operation, they only provide the controller file system path to be used by your application.
CAUTION!
When added to the VS Designer from the Toolbox, these controls will be placed in the components pane. They must be explicitly removed by a call to their
Dispose
method, e.g. in the
Dispose
method of the class that created them.
Illustration
Below is an illustration of the
GTPUSaveFileDialog
. The other file dialogs have almost the same appearance and the way they work is very similar. Using the icons of the command bar you create new folders and browse the controller file system. Together with the list and the
3HAC028083-001 Revision: D
Continues on next page
119
5 Using the FlexPendant SDK
5.3.13. GTPUFileDialog
Continued
textbox, you specify a remote path. The FileName property should be read to retrieve this path. It returns the complete path to the controller file system, even though only the file name is visible in the File name textbox
120
6.3.13_2
6.3.13_1
Note! The button after the File name textbox opens the virtual keyboard, enabling the user to change the name of the file to be saved. The Filter property of the control is set to
TEXT(*.txt)|*.txt. The first part of the setting is displayed in the filter textbox.
This is the Properties window of this dialog:
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.3.13. GTPUFileDialog
Continued
Implementation details
The Properties window gives a clear description of a selected property, as can be seen in the figure above. Here only a few important properties will be detailed:
Property
Filter
FileName
InitialDirectory
Details
Carefully observe the string format when you set this property, e.g.: Program Files (*.pgf)|*.pgf
The first part is displayed in the combo box and the second part is used by the SDK to retrieve the correct files to be displayed in the list. You can also specify several filters, which the user can choose from.
Program Files (*.pgf)|*.pgf|All Files (*.*)|*.*;
Cannot be accessed in design-time by using the
Properties window, but should be manually coded when the file dialog is launched if it is a save file dialog.
When the dialog is closed, you should read this property.
It holds the remote path and file name of the file to be opened, or the remote path and file name of the file to be saved.
Note! Remember that remote refers to the controller file system and local to the FlexPendant file system.
Cannot be accessed in design-time by using the
Properties window. Specifies the initial directory to be displayed by the file dialog box.
NOTE!
For your program to be able to use the controller path selected by the end user, you need to read the FileName property at the
Closing/Closed
event of the file dialog.
Example
This piece of code sets
InitialDirectory
and
FileName
, then sets up a subscription to the
Closed
event and finally displays the
GTPUSaveFileDialog saveFileDialog.InitialDirectory = initialDir; saveFileDialog.FileName = programName; saveFileDialog.Closed += new
EventHandler(SaveProgram_FileDialog_EventHandler); saveFileDialog.ShowMe(_parent);
The code of the
SaveProgram_FileDialog_EventHandler
method retrieves the specified path of the remote file system, including the file name, by reading the
FileName property: string remotePath = saveFileDialog.Filename;
NOTE!
The file has not yet been saved to the robot controller. To do that you should call
FileSystem.PutFile using the retrieved path as the remoteFile argument. Likewise, to load a specified remote file to the FlexPendant file system you should use the retrieved path in the call to
FileSystem.GetFile.
3HAC028083-001 Revision: D 121
5 Using the FlexPendant SDK
5.3.14. DataBinding of RAPID data and IO signals
5.3.14. DataBinding of RAPID data and IO signals
What is databinding?
Databinding is the process of binding a property of a GUI control to a data source, so that the property automatically reflects the value of the data source. In .NET CF 2.0 this functionality was simplified thanks to the new
BindingSource
class. This class encapsulates the complexity related to setting up and managing databinding.
FlexPendant SDK classes to be used as binding sources
In the FlexPendant SDK there are two classes that inherit .NET
BindingSource
:
RapidDataBindingSource
and
SignalBindingSource.
These classes enable binding to
RAPID data and IO signals respectively. They belong to the
ABB.Robotics.DataBinding
namespace and the assembly you need to reference is ABB.Robotics.DataBinding.dll.
RapidDataBindingSource
By using
RapidDataBindingSource
an automatic update of the bound GUI control takes place when the value of the specified RAPID data source in the controller has changed, or when the control is repainted.
SignalBindingSource
By using
SignalBindingSource an automatic update of the bound GUI control takes place when the value of the specified IO signal in the controller has changed, or when the control is repainted.
NOTE!
It is only possible to use persistent RAPID data (PERS) as data source.
NOTE!
If you want to let users modify RAPID data, launching the standard FlexPendant application
Program Data from your application is probably the best alternative. See
Using standard dialogs to modify data on page 131
for information about how to do it.
GUI example
Many different controls can be used with binding sources, e.g.
TpsLabel
,
TextBox
,
ListView
etc. The figure below shows two
System.Windows.Forms.DataGrid
controls that each bind to several objects defined in a
RapidDataBindingSource
and a
122
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.3.14. DataBinding of RAPID data and IO signals
Continued
SignalBindingSource
. The labels in each
GroupBox
are bound to the same sources. As you see the grid displays all objects defined in the
BindingSource
control, whereas each label displays the currently selected grid row.
When a signal or a data value changes this GUI is automatically updated with the new value.
You do not have to write any code make this happen, as setting up subscriptions and updating the user interface is done by the underlying implementation.
6.3.14_1
3HAC028083-001 Revision: D
Continues on next page
123
5 Using the FlexPendant SDK
5.3.14. DataBinding of RAPID data and IO signals
Continued
CAUTION!
To avoid any memory leaks an explicit call to the
Dispose
method of
BindingSource controls must be made. However, the wrapper-objects
SignalObject
and
RapidDataObject
created for you are disposed of under the hood, so you do not need to worry about it.
How to use the VS designer for data binding
This section explains how to create the FlexPendant view shown in the previous section. First a
RapidDataBindingSource
control with bindings to specified RAPID data is created.Then the DataBindings property of a
TpsLabel
is used to bind the label to the binding source. Finally a standard .NET
DataGrid
is bound to the same binding source.
Step Action
1. Start by dragging a
RapidDataBindingSource
from the Toolbox to the Designer. It will be placed in the Components pane under the form. Open the Properties window and select the RapidDataList property to add the RAPID data you are interested in.
For each new RapidDataObject member you must specify module name, task name and name of the persistent RAPID data to bind.
124
6.3.14_2
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.3.14. DataBinding of RAPID data and IO signals
Continued
Step Action
2. The next step is to open the Properties window for the label that is to display the value of the RAPID data. Expand the DataBindings node and select Advanced.
6.3.14_3
3HAC028083-001 Revision: D
Continues on next page
125
5 Using the FlexPendant SDK
5.3.14. DataBinding of RAPID data and IO signals
Continued
Step Action
3. In the Advanced Binding dialog box that appears, choose the already created
RapidDataBindingSource
in the Binding combo box, at the same time specifying which one of the RapidDataObject properties you want to bind to, in this case Value.
(The other properties available are variable name, task name and module name, as can be seen in the figure in step 1.)
You also select your preferred Data Source Update Mode, usually OnProperty-
Changed. The yellow marking in the list to the left shows that the binding has been done to the Text property of the label. When a control has been bound to a data source you will see the same yellow marking in its Properties window, at the bound property. See figure of step 2.
126
6.3.14_4
NOTE!
If a label has been bound to a data source with several member objects, the first one in the list is the one by default displayed by the label. If the selected index of the list changes (if the user selects a row in the grid for example) the label is updated auto-
matically to show the value of the selected index. See the figure in
.
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.3.14. DataBinding of RAPID data and IO signals
Continued
Step Action
4. Now launch the Properties window of the
DataGrid
control. Set ColumnHeader-
Visible to true and select your data source at the DataSource property.
6.3.14_5
NOTE!
The
DataGrid
control displays only one row in design-time (See the figure of step 1).
In run-time, however, the entire collection of RapidDataObject members is displayed
(see the figure in
SuspendBinding/ResumeBinding
SuspendBinding()
and
ResumeBinding()
have extended functionality compared to the methods of the inherited
BindingSource
class. Removing/adding subscriptions have been added, as subscribing to signals and RAPID data can be resource consuming. These methods can be used in the
Deactivate/Activate
methods, which are executed each time the user switches back and forth between different applications using the FlexPendant task bar. See
Application Framework usage - ITpsViewActivation on page 190
If you suspend the binding you no longer get any updates if the data source is changed.
However, the binding still exists, so if DataSourceUpdateMode is set to OnValidation the value will be updated when you repaint the control, as the value from the controller will be read before it is repainted.
Method
SuspendBinding
ResumeBinding
Description
Suspends the binding and value change event.
Resumes the binding and value change event.
3HAC028083-001 Revision: D 127
5 Using the FlexPendant SDK
5.4.1. Using launch service
5.4 Launching other views
5.4.1. Using launch service
Overview
The FlexPendant SDK provides a launch service, which enables a RAB application to start a standard ABB application, such as the program editor or the jogging view.
It is also possible to start another custom application by specifying proxy assembly name and the application view class.
For information about how to add and launch another view of your own application, see
Adding a view to a custom application on page 99
NOTE!
To launch a view in order to edit a specified rapid data instance, another mechanism is available. See
Using standard dialogs to modify data on page 131
for details.
ITpsViewSetup Install
It is only classes that inherit the
ITpsViewSetup
interface that can launch other applications.
The
Install
method, which is called when your custom application is launched, has a sender argument. Your application needs to save this object to be able to use the
ITpsViewLaunchServices
interface. It is used by the launch service to call
LaunchView and
CloseView
.
VB:
//declaration
Private iTpsSite As ITpsViewLaunchServices
.....
//Install method of the TpsView class
Function Install(ByVal sender As System.Object, ByVal data As
System.Object) As Boolean Implements ITpsViewSetup.Install
If TypeOf sender Is ITpsViewLaunchServices Then
// Save the sender object for later use
Me.iTpsSite = DirectCast(sender, ITpsViewLaunchServices)
Return True
End If
Return False
End Function
128
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.4.1. Using launch service
Continued
C#:
//declaration private ITpsViewLaunchServices iTpsSite;
......
//Install method of the TpsView class bool ITpsViewSetup.Install(object sender,object data)
{ if (sender is ITpsViewLaunchServices) {
// Save the sender object for later use this.iTpsSite = sender as ITpsViewLaunchServices; return true;
} return false;
}
Launching standard views
Using the
FpStandardView
enumerator, the following standard views can be started using the launch services:
• Program editor
•
Program data
• Jogging
•
Logoff
•
Backup/Restore
TIP!
Launching the Program data view is the best way to let end-users create new RAPID data.
NOTE!
To launch the program editor an initialization object of
RapidEditorInitData
type can be used as argument. It specifies the task, module and row that the Program editor should display when it opens. For the other standard views no
InitData
can be used.
LaunchView / CloseView example
In the example below, the program editor is launched at a specified routine. First initData is created. Then the reference to the sender object, retrieved by the
Install
method in the previous example, is used to call
LaunchView
.
The cookie out argument is later used to specify the view to be closed by the
CloseView method.
VB:
Dim initData As RapidEditorInitData = New RapidEditorInitData
(ATask, AModule, ARoutine.TextRange.Begin.Row)
If Not (Me.iTpsSite.LaunchView(FpStandardView.RapidEditor, initData, True, Me.cookieRapidEd) = True) Then
GTPUMessageBox.Show(Me, Nothing, "Could not start RapidEditor application")
Return
Continues on next page
3HAC028083-001 Revision: D 129
5 Using the FlexPendant SDK
5.4.1. Using launch service
Continued
C#:
End If
......
Me.iTpsSite.CloseView(Me.cookieRapidEd)
RapidEditorInitData initData = new RapidEditorInitData(task, module,routine.TextRange.Begin.Row; if(this.iTpsSite.LaunchView(FpStandardView.RapidEditor,initData, true,out this.cookieRapidEd)!= true) {
GTPUMessageBox.Show(this, null,"Could not start RapidEditor application"); return;
}
.....
this.iTpsSite.CloseView(this.cookieRapidEd);
What happens if the specified view is already open when the call is made? The third argument specifies application behavior in this case. If true
, another instance of the view is launched.
If false
, the already opened view gets focus. Notice, however, that creating a new instance is not possible for all standard views. The Jogging view, for example, is not allowed multiple instances.
Launching custom applications
The launch service can also be used to launch another RAB application. The name of the proxy assembly along with the fully qualified class name should be used as arguments.
VB:
If Not (Me.iTpsSite.LaunchView("TpsViewCustomApp.gtpu.dll",
"ABB.Robotics.SDK.Views.TpsViewCustomApp", Nothing, True,
Me.cookieUser) = True) Then
GTPUMessageBox.Show(Me, Nothing, "Could not start User application")
Return
End If
C#: if (this.iTpsSite.LaunchView("TpsViewCustomApp.gtpu.dll",
"ABB.Robotics.SDK.Views.TpsViewCustomApp", null, true, out this.cookieUser)!= true) {
GTPUMessageBox.Show(this, null,"Could not start User application"); return;
}
NOTE!
It is the namespace of the proxy assembly, ABB.Robotics.SDK.Views,which should be used to specify the
TpsView class.
NOTE!
By using the argument cookieUser your application can close the launched custom application in the same way as in the
Launching standard views on page 129
example above.
130 3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.4.2. Using standard dialogs to modify data
5.4.2. Using standard dialogs to modify data
Overview
The
FpRapidData
,
FpToolCalibration
and
FpWorkObjectCalibration
dialogs take a
RapidData
reference as argument. When the dialog is opened it allows the user to directly operate on the referenced RapidData object, for example modifying a RAPID data variable or calibrate a work object. These dialogs are the ones used by the standard ABB applications.
They are ready-made and cannot be modified, except for the title.
Creating the dialog
As with all secondary dialogs, the reference to the dialog should be declared as a class variable. This is to make sure that the reference is available for
Dispose
. The
RapidData reference can be declared locally if it is disposed immediately after use, or else as a class variable. When the dialog has been created the title can be set using the
Text
property. A
Closed
event handler should be added to dispose the dialog. All three dialogs are created in the same way:
VB:
C#:
Private ARapidData As RapidData
Friend WithEvents FpRD As FpRapidData
.....
Me.ARapidData = Me.AController.Rapid.GetRapidData(ATaskName,
AModuleName, AVariableName)
Me.FpRD = New FpRapidData(Me.ARapidData)
Me.FpRD.Text = Me.ARapidData.Name
AddHandler Me.FpRD.Closed, AddressOf Me.FpRD_Closed
Me.FpRD.ShowMe(Me) private FpRapidData fpRD; private RapidData aRapidData;
......
this.aRapidData = this.aController.Rapid.GetRapidData(taskName, moduleName, variableName); this.fpRD = new FpRapidData(this.aRapidData); this.fpRD.Text = this.aRapidData.Name; this.fpRD.Closed += new EventHandler( fpRD_Closed); this.fpRD.ShowMe(this);
3HAC028083-001 Revision: D
Continues on next page
131
5 Using the FlexPendant SDK
5.4.2. Using standard dialogs to modify data
Continued
NOTE!
Verify that the
RapidData
is of correct
RapidDataType
for the dialog before using it, i.e. tooldata
for the FpToolCalibration dialog and wobjdata
for the FpWorkObjectCalibration
NOTE!
The FpRapidData dialog is created with a RapidData as in argument. If the RapidData is an array, an index argument is used to specify which element should be displayed (the first element is 1).
Type checking
When calling the
FpToolCalibration
or
FpWorkObjectCalibration
constructor the
RapidData
value should be type checked before use:
VB:
C#:
If TypeOf Me.ARapidData.Value Is ToolData Then
Me.FpTC = New FpToolCalibration(Me.ARapidData)
.....
End If if (this.aRapidData.Value is ToolData)
{ this.fpTC = new FpToolCalibration(this.aRapidData);
....
}
132 3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.1. ABB.Robotics.Controllers
5.5 Using the Controller API
5.5.1. ABB.Robotics.Controllers
Controller API
To access the functions of the robot controller you utilize the class libraries of the FP SDK called Controller Application Programming Interface or CAPI. The assembly you need to reference to use controller functionality is ABB.Robotics.Controllers.dll.
CAPI domains
The top CAPI object is the
ABB.Robotics.Controllers.Controller
, which has to be created before any access to the robot controller.
The class libraries are organized in different domains (namespaces), as shown by the contents tab of the FP SDK Reference below. The name of a domain tells you something about the kind of services you can expect from it.
6.4.1_1
3HAC028083-001 Revision: D
Continues on next page
133
5 Using the FlexPendant SDK
5.5.1. ABB.Robotics.Controllers
Continued
CAPI and controller domains
This is a simplified illustration of how some
ABB.Robotics.Controllers
domains communicate with their respective domains in the robot controller:
6.4.1_2
NOTE!
In the normal case, a single
Controller
object is created and used throughout the application, its lifetime corresponding to that of the application.
What controller functionality is provided?
Plenty of robot controller functionality is offered by the classes and methods of the
FlexPendant SDK.
This table presents short descriptions of the kind of services that the different CAPI domains provide:
CAPI domain Services
Controllers
ConfigurationDomain Read or write the value of a configuration parameter to the configuration database of the controller.
EventLogDomain
FileSystemDomain
IOSystemDomain
Notification when a new event log message has been written to the controller. Title, message, category, sequence number and time stamp of the message.
Create, rename or remove files and directories in the controller file system. Retrieve a file from the controller and store it on the
FlexPendant and vice versa.
Read and modify I/O signals. Notify when a signal value has changed.
MotionDomain
Information about the controller, such as IP address, current user,
Mac address, operating mode, controller state etc. Notification when operating mode, state or mastership has changed. Backup and restore. Check if the user has the required UAS grant etc.
Get/set the coordinate system and motion mode for jogging of the active mechanical unit. Information whether the mechanical unit is calibrated or not. Provide name, task, number of axes, active tool and work object etc. of the mechanical unit. Notify when data of the mechanical unit has changed. Send a start jogging or a stop jogging request to the robot controller.
134
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.1. ABB.Robotics.Controllers
Continued
CAPI domain
RapidDomain
SystemInfoDomain
Services
Notification when execution status has changed. Start and stop
RAPID execution. Load Rapid programs. Create, read and write
RAPID data. Notification when RAPID data or RAPID program has changed. Notification when program pointer has changed. Search
RAPID symbols etc.
Information about the active system of the robot controller, e.g.
RobotWare version, system name, release and system paths, existing system options and installed additional options.
Releasing memory
Using CAPI you will create objects that reference unmanaged resources. (See
.) It is necessary to explicitly deallocate the memory of such objects by calling their
Dispose
method when they are no longer needed (at application shut down at the latest).
Otherwise your application will leak memory, which is a scarce resource on the FlexPendant platform.
NOTE!
You may prevent memory leaks and other pitfalls, by studying the chapter
FlexPendant applications on page 181
.
FP SDK Reference
Although this manual covers a great deal of the FP SDK functionality, it is by no means complete. The FP SDK Reference, which you open from Windows Start button, is the complete reference to the functionality offered by the class libraries.
It also gives valuable code samples and remarks about methods requiring different UAS grants etc., which is not included in this manual.
3HAC028083-001 Revision: D 135
5 Using the FlexPendant SDK
5.5.2. Accessing the controller
5.5.2. Accessing the controller
Overview
Making use of controller functionality requires special attention. Disposal of CAPI objects when closing a view or the entire application is vital to save memory. Another pitfall that must be avoided is updating the user interface on a worker thread.
Controller instance
Before accessing the controller functionality you need to instantiate the
Controller
object.
The best place to do this is normally in the
Install
method, which is called by TAF after the constructor of your view class has executed.
The
Controller
declaration should be done on class scope level:
VB:
Private AController As Controller
C#: private Controller aController;
The recommendation is to instantiate the
Controller
object in the
Install
method:
VB:
AController = New Controller
C#: aController = new Controller();
136
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.2. Accessing the controller
Continued
Using the
Controller
object you can access IO signals, RAPID data variables, event log messages etc. Most of these objects will be created explicitly and should be disposed of explicitly.
NOTE!
Avoid placing any code that may result in an exception before the method
InitializeComponent
. Then at least you have a user interface, where you can display a
MessageBox
with information about what went wrong.
NOTE!
It is recommended that if several classes need to access the controller, they all reference the same
Controller
object.
Subscribing to controller events
The
Controller
object provides several public events, which enable you to listen to operating mode changes, controller state changes, mastership changes etc.
VB:
AddHandler AController.OperatingModeChanged, AddressOf UpdateOP
AddHandler AController.StateChanged, AddressOf UpdateState
AddHandler AController.MastershipChanged, AddressOf UpdateMast
AddHandler AController.BackupFinished, AddressOf UpdateBack
C#:
AController.OperatingModeChanged += new
OperatingModeChangedEventHandler(UpdateOP);
AController.MastershipChanged += new
MastershipChangedEventHandler(UpdateMast);
Controller.BackupFinished += new
BackupFinishedEventHandler(UpdateBack);
Controller.StateChanged += new
StateChangedEventHandler(UpdateState);
3HAC028083-001 Revision: D
Continues on next page
137
5 Using the FlexPendant SDK
5.5.2. Accessing the controller
Continued
Create a backup
Using the
Controller
object you can call the
Backup
method. The argument is a string describing the directory path on the controller where the backup should be stored. As the backup process is performed asynchronously you can add an event handler to receive a
BackupCompleted
event when the backup is completed.
VB:
Dim BackupDir As String = "(BACKUP)$"+BackupDirName
AddHandler Me.AController.BackupCompleted, AddressOf
AController_BackupCompleted)
Me.AController.Backup(BackupDir)
C#: string backupDir = "(BACKUP)$"+backupDirName; this.aController.BackupCompleted += new
BackupEventHandler(controller_BackupCompleted); this.aController.Backup(backupDir);
NOTE!
There is also a
Restore
method available. The FP SDK reference is the complete
FlexPendant SDK programming guide and is more detailed than this manual. For the
Backup and
Restore
methods, for example, there are parameter descriptions, remarks, code examples etc.
Dispose
NOTE!
Controller events use their own threads. Study
Controller events and threads on page 67
find out how to avoid threading conflicts.
CAUTION!
Do not rely on receiving an initial event when setting up/activating a controller event. There is no guarantee an event will be triggered, so you had better read the initial state from the controller.
138
The disposal of the
Controller
object should be done in the
Uninstall or Dispose method of the application view class.
Make a check first that disposal has not already been done. Do not forget to remove any subscriptions to controller events before the
Dispose()
call:
VB:
If Not AController Is Nothing Then
RemoveHandler AController.OperatingModeChanged, AddressOf
OpMChange
AController.Dispose()
AController = Nothing
End If
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.2. Accessing the controller
Continued
C#: if (aController != null)
{ aController.OperatingModeChanged -= new
OperatingModeChangedEventHandler(OpMChange); aController.Dispose(); aController = null;
}
CAUTION!
VB programmers should be aware that it is a bit tricky to use
WithEvents
together with the
Dispose pattern on the .NET platform. When you use
WithEvents
the .NET framework automatically removes any subscriptions when the object is set to
Nothing
. If you look at the code sample above, which does NOT use
WithEvents
, you will understand why such behavior causes problems. When the controller reference is set to
Nothing
and the .NET framework tries to remove its subscription, the internal controller object has already been removed by the
Dispose
call in the preceding statement, and a
NullReferenceException is thrown. This is not specific to the FlexPendant SDK, but a Microsoft issue. To avoid it you are advised to use
AddHandler
and
RemoveHandler
like in the example.
3HAC028083-001 Revision: D 139
5 Using the FlexPendant SDK
5.5.3.1. Working with RAPID data
5.5.3. Rapid domain
5.5.3.1. Working with RAPID data
Overview
The
RapidDomain
namespace enables access to RAPID data in the robot system. There are numerous FP SDK classes representing the different RAPID data types. There is also a
UserDefined
class used to reference RECORD structures in RAPID.
The
ValueChanged
event enables notification from the controller when persistent RAPID data has changed.
TIP!
A convenient and user-friendly way to enable the end-user of your application to read and write to specific RAPID data is using the standard FlexPendant Program Data view. See
Using standard dialogs to modify data on page 131
for details about how this can be done.
TIP!
Using databinding for RAPID data is a quick way of implementing access to RAPID data.
See how this works in
DataBinding of RAPID data and IO signals on page 122
Providing the path to the RAPID data
To read or write to RAPID data you must first create a
RapidData
object. The path to the declaration of the data in the controller is passed as argument. If you don’t know the path you need to search for the RAPID data by using the
SearchRapidSymbol
functionality. See
SearchRapidSymbol method on page 157
.
Direct access
Direct access requires less memory and is faster, and is therefore recommended if you do not need to use the task and module objects afterwards.
The example below shows how to create a
RapidData
object that refers to the RAPID data instance “reg1” in the USER module.
VB:
Dim Rd As RapidData = Me.AController.Rapid.GetRapidData(
"T_ROB1", "USER", "reg1")
C#:
RapidData rd = aController.Rapid.GetRapidData("T_ROB1", "USER",
"reg1");
Hierarchical access
140
If you need the task and module objects hierarchical access can be more efficient.
GetRapidData
exists in the Rapid, Task and Module class.
VB:
Rd = AController.Rapid.GetTask("T_ROB1").GetModule("USER").
GetRapidData("reg1")
C#: rd = aController.Rapid.GetTask("T_ROB1").GetModule("USER").
GetRapidData("reg1");
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.3.1. Working with RAPID data
Continued
Accessing data declared in a shared module
If your application is to be used with a multi-move system (a system with one controller and several motion tasks/robots), it may happen that the RAPID instance you need to access is declared in a -Shared RAPID module. Such a module can be used by all tasks, T_ROB1,
T_ROB2 etc.
This example shows how to create a
RapidData
object that refers to the instance “reg100”, which is declared in a shared module.
VB:
Dim Rd As RapidData = Me.AController.Rapid.GetRapidData("reg100")
C#:
RapidData rd = aController.Rapid.GetRapidData("reg100");
Another possibility is using the
Task
object to access the RAPID instance, like this:
Task tRob1 = aController.Rapid.GetTask("T_ROB1");
RapidData rData = tRob1.GetRapidData("reg100");
3HAC028083-001 Revision: D
Continues on next page
141
5 Using the FlexPendant SDK
5.5.3.1. Working with RAPID data
Continued
NOTE!
If
GetRapidData
is called from
Rapid
the RAPID data will be found even if the -Shared module is configured to be hidden.
NOTE!
If the RAPID data does not exist, the return value is
Nothing/null
and an
ArgumentNullException
is thrown. A null check should be performed before trying to use the object.
Creating an object representing the RAPID data value
The
RapidData
object stores the path to the RAPID data. But this is not enough if you want to access its value (at least not if you want to modify it). To do that you need to create another object, which represents the value of the RAPID data.
In the
RapidDomain
namespace there are types representing the different RAPID data types.
To create the object needed to represent the RAPID data value you use the
RapidData property
Value
and cast it to the corresponding type, e.g.
Num, Bool or
Tooldata
.
This is how this is done if you want to access the value of a RAPID data of the RAPID data type bool
:
VB:
’declare a variable of data type RapidDomain.Bool
Dim rapidBool As RapidDomain.Bool
Dim rd As RapidData = Me.AController.Rapid.GetRapidData( "T_ROB1",
"MainModule", "flag" )
’test that data type is correct before cast
If TypeOf rd.Value Is RapidDomain.Bool Then rapidBool = DirectCast(rd.Value, RapidDomain.Bool)
’check if the value of the RAPID data is true
If (rapidBool.Value) Then
’ Do something...
End If
EndIf
C#:
//declare a variable of data type RapidDomain.Bool
RapidDomain.Bool rapidBool;
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;
}
142
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.3.1. Working with RAPID data
Continued
If you just want to read this variable you can use this technique instead of creating a
RapidDomain.
Bool
object:
VB:
C#:
Dim b As Boolean = Convert.ToBoolean(rd.Value.ToString) bool b = Convert.ToBoolean(rd.Value.ToString());
The
ToolData
type (representing the RAPID data type tooldata)
can be created like this:
VB:
Dim ATool As ToolData
If 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 method
All RapidDomain structures representing RAPID data types implement the
IRapidData interface. It has a
ToString
method, which returns the value of the RAPID data in the form of a string. This is a simple example: string boolValue = rapidBool.ToString();
The string is formatted according to the same principle as described in
IRapidData.FillFromString method on page 144
Here is an example of a more complex data type. The
ToolData Tframe
property is of the
Pose
type. Its
Trans
value is displayed in a label in the format [x, y, z].
VB:
C#:
Me.Label1.Text = ATool.Tframe.Trans.ToString() this.label1.Text = aTool.Tframe.Trans.ToString();
3HAC028083-001 Revision: D
Continues on next page
143
5 Using the FlexPendant SDK
5.5.3.1. Working with RAPID data
Continued
IRapidData.FillFromString method
The
IRapidData
interface also has a
FillFromString
method, which fills the object with a valid RAPID string representation. The method can always be used when you need to modify RAPID data. Using the method with the
RapidDomain.Bool
variable used earlier in the chapter will look like this: rapidBool.FillFromString("True")
Using it for a
RapidDomain.Num
variable is similar: rapidNum.FillFromString("10")
String format
The format is constructed recursively. An example is the easiest way of illustrating this.
Example:
The
RapidDomain.Pose
structure corresponds to the RAPID data type pose
, which describes how a coordinate system is displaced and rotated around another coordinate system.
public struct Pose : IRapidData
{ public Pos trans; public Orient rot;
}
This is an example in RAPID:
VAR pose frame1;
...
frame1.trans := [50, 0, 40]; frame1.rot := [1, 0, 0, 0];
The frame1 coordinate transformation is assigned a value that corresponds to a displacement in position where X=50 mm, Y=0 mm and Z=40 mm. There is no rotation.
As you see, the
RapidDomain.Pose
structure consists of two other structures, trans and rot.
The trans structure consists of three floats and the and rot structure consists of four doubles.
The
FillFromString
format for a
Pose
object is “[[1.0, 0.0, 0.0, 0.0][10.0, 20.0, 30.0]]”.
This piece of code shows how to write a new value to a RAPID pose
variable:
VB:
C#:
If TypeOf rd.Value Is Pose Then
Dim rapidPose As Pose = DirectCast(rd.Value, Pose) rapidPose.FillFromString("[[1.0, 0.0, 0.0, 0.0][10, 20, 30]]") rd.Value = rapidPose
End If 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;
}
144
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.3.1. Working with RAPID data
Continued
NOTE!
Using the same principle arbitrarily long RAPID data types can be represented.
NOTE!
The string format must be carefully observed. If the string argument has the wrong format, a
RapidDataFormatException
is thrown.
Writing to RAPID data
Writing to RAPID data is only possible using the type cast
RapidData
value, to which the new value is assigned. To transfer the new value to the RAPID data in the controller you must finally assign the .NET object to the
Value
property of the RapidData object. This example uses the rapidBool object created in
Creating an object representing the RAPID data value on page 142
.
VB:
’Assign new value to .Net variable rapidBool.Value = False
’Write the new value to the data in the controller rd.Value = rapidBool
C#:
//Assign new value to .Net variable rapidBool.Value = false;
//Write to new value to the data in the controller rd.Value = rapidBool;
This was an easy example, as the value to change was a simple bool
. Often, however, RAPID uses complex structures. By using the
FillFromString
method you can assign a new value to any
RapidData
and write it to the controller.
The string must be formatted according to the principle described in the previous section. The following example shows how to write a new value to the pos
structure (x, y, z) of a RAPID tooldata:
VB:
Dim APos As Pos = New Pos
APos.FillFromString("[2,3,3]")
Me.ATool.Tframe.Trans = APos
Me.Rd.Value = Me.ATool
C#:
Pos aPos = new Pos(); aPos.FillFromString("[2,3,3]"); this.aTool.Tframe.Trans = aPos; this.rd.Value = this.aTool;
3HAC028083-001 Revision: D
Continues on next page
145
5 Using the FlexPendant SDK
5.5.3.1. Working with RAPID data
Continued
NOTE!
The new value is not written to the controller until the last statement is executed.
Letting the user know that RAPID data has changed
In order to be notified that RAPID data has changed you need to add a subscription to the
ValueChanged
event of the
RapidData
instance. Note, however, that this only works for
persistent RAPID data.
Add subscription
This is how you add a subscription to the
ValueChanged
event:
VB:
Addhandler Rd.ValueChanged, AddressOf Rd_ValueChanged
C#: this.rd.ValueChanged += rd_ValueChanged;
Handle event
Implement the event handler. Remember that controller events use their own threads, and avoid Winforms threading problems by the use of
Control.Invoke
, which forces the execution from the background thread to the GUI thread.
VB:
Private Sub Rd_ValueChanged(ByVal sender As Object, ByVal e As
DataValueChangedEventArgs)
Me.Invoke(New EventHandler (AddressOf UpdateGUI), sender, e)
End Sub
C# private void rd_ValueChanged(object sender,
DataValueChangedEventArgs e)
{ this.Invoke(new EventHandler (UpdateGUI), sender, e);
}
Controller events and threads on page 67
to learn more about potential threading
conflicts in RAB applications.
Read new value from controlller
Update the user interface with the new value. As the value is not part of the event argument, you must use the
RapidData Value
property to retrieve the new value:
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
146
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.3.1. Working with RAPID data
Continued
C# private void UpdateGUI(object sender, System.EventArgs e)
{
ToolData tool1= (ToolData)this.rd.Value; this.label1.Text = tool1.Tframe.Trans.ToString();
}
NOTE!
Subscriptions work only for RAPID data declared as PERS.
RapidData disposal
Always dispose of
RapidData
objects when they are no longer needed. If you want to reuse a
RapidData
object, you should make sure that you dispose of the current object first.
VB:
If Not Rd Is Nothing Then
Rd.Dispose()
Rd = Nothing
End If
C#: if (rd != null)
{ rd.Dispose(); rd = null;
}
3HAC028083-001 Revision: D 147
5 Using the FlexPendant SDK
5.5.3.2. Handling RAPID arrays
5.5.3.2. Handling RAPID arrays
Overview
In RAPID you can have up to three dimensional arrays. These are accessible by using a
RapidData
object like any other RAPID data.
There are mainly two ways of accessing each individual element of an array: by indexers or by an enumerator.
TIP!
A convenient and user-friendly way of reading and writing array elements is using the standard Program Data view of the FlexPendant. You provide the element you want to have displayed as argument, and the user can view or manipulate the item the way it is usually done
Using standard dialogs to modify data on page 131
ArrayData object
If the
RapidData references a RAPID array is
Value
property returns an object of
ArrayData
type. Before making a cast, check the type using the is
operator or by using the
IsArray
property on the
RapidData
object.
VB:
Dim RD As RapidData = AController.Rapid.GetRapidData("T_ROB1",
"User", "string_array")
If RD.IsArray Then
Dim AD As ArrayData = DirectCast( RD.Value,ArrayData)
.....
End If
C#:
RapidData rd = aController.Rapid.GetRapidData("T_ROB1", "User",
"string_array"); if (rd.IsArray)
{
ArrayData ad = (ArrayData)rd.Value;
.....
}
Array dimensions
The dimension of the array is returned by the Rank property. If you need to check the length of the individual arrays you can use the
GetLength
method on the
ArrayData
object passing the dimension index as argument.
VB:
C#:
Dim ARank As Integer = AD.Rank
Dim Len As Integer = AD.GetLength(ARank) int aRank = ad.Rank; int len = ad.GetLength(aRank);
148
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.3.2. Handling RAPID arrays
Continued
Array item access by using indexers
By the use of indexers you can access each array element, even in three dimensional arrays.
A combination of the
GetLength
method and
For
loops makes it possible to access any item:
VB:
Dim ASum As Double = 0R
Dim ANum As Num
If AD.Rank = 1 Then
For I As Integer = 1 To AD.Length
ANum = DirectCast(ad.[I], Num)
ASum += DirectCast(ANum, Double)
Next
ElseIf AD.Rank = 2 Then
For I As Integer = 1 To AD.GetLength(1)
For J As Integer = 1 To AD.GetLength(2)
ANum = DirectCast(ad[I, J], Num)
ASum += DirectCast(ANum, Double)
Next
Next
Else
For I As Integer = 1 To AD.GetLength(1)
For J As Integer = 1 To AD.GetLength(2)
For K As Integer = 1 To AD.GetLength(3)
ANum = DirectCast(ad[I, J, K], Num)
ASum += DirectCast(ANum, Double)
Next
Next
Next
End If
C#: double sum = 0d;
Num aNum; if (ad.Rank == 1) { for (int i = 1; i <= ad.Length; i++)
{ aNum = (Num)ad.[i]; aSum += (double)ANum;
}
3HAC028083-001 Revision: D
Continues on next page
149
5 Using the FlexPendant SDK
5.5.3.2. Handling RAPID arrays
Continued
} elseif (ad.Rank == 2)
{ for(int i = 1; i< ad.GetLength(1); i++)
{ for (int j = 1; j <= ad.Length; j++)
{ aNum = (Num)ad.[i,j]; aSum += (double)ANum;
}
}
} else { for(int i = 1; i< ad.GetLength(1); i++)
{ for(int j = 1; j< ad.GetLength(2); j++)
{ for (int k = 1; k <= ad.GetLength(3); k++)
{ aNum = (Num)ad.[i, j, k]; aSum += (double)ANum;
}
}
}
}
Array item access using enumerator
You can also use the enumerator operation ( foreach
) like it is used by collections in .NET.
Notice that it can be used for both one dimension and multi-dimensional arrays to access each individual element. The previous example is a lot simpler this way:
VB:
C#:
Dim ASum As Double = 0R
Dim ANum As Num
For Each ANum As Num In AD
ASum += DirectCast(ANum, Double)
Next double sum = 0d;
Num aNum; foreach(Num aNum in ad)
{ aSum += (double)ANum;
}
150 3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.3.3. ReadItem and WriteItem methods
5.5.3.3. ReadItem and WriteItem methods
Overview
An alternative way of accessing RAPID data stored in an array are the
ReadItem
and
WriteItem
methods.
ReadItem method
Using the
ReadItem
method you can directly access a RAPID data item in an array, e.g. an array with RobTargets or Nums. The index to the item is explicitly specified in the
ReadItem call. The first item is in position 1, i.e. the array is 1-based as in RAPID.
This example retrieves the second Num value in the first array of the RAPID data variable referenced by rd.
VB:
Dim ANum As Num aNum = DirectCast(rd.ReadItem(1, 2), Num)
C#:
Num aNum = (Num)rd.ReadItem(1, 2);
WriteItem method
In the same manner it is possible to use the
WriteItem
method to write to an individual
RAPID data item in an array. This example shows how to write the result of an individual robot operation into an array representing a total robot program with several operations:
VB:
Dim ANum As Num = New Num(OPERATION_OK) rd.WriteItem(ANum, 1, 2)
C#:
Num aNum = new Num(OPERATION_OK); rd.WriteItem(aNum, 1, 2);
NOTE!
If the index is out of bounds an
IndexOutOfRangeException
will be thrown.
3HAC028083-001 Revision: D 151
5 Using the FlexPendant SDK
5.5.3.4. UserDefined data
5.5.3.4. UserDefined data
Overview
You often work with RECORD structures in RAPID code. To handle these unique data types a
UserDefined
class has been implemented. This class has properties and methods to handle individual components of a RECORD.
In some cases implementing your own .NET structure can improve application design and code maintenance.
Creating UserDefined object
The
UserDefined
constructor takes a
RapidDataType
object as argument. To retrieve a
RapidDataType
object the path to the declaration of the RAPID data type is passed as argument.
This example creates a
UserDefined
object referencing the RAPID RECORD processdata:
VB:
Dim rdt As RapidDataType rdt = Me.controller.Rapid.GetRapidDataType("T_ROB1", "MyModule",
"processdata")
Dim processdata As UserDefined = New UserDefined(rdt)
C#
RapidDataType rdt; rdt = this.controller.Rapid.GetRapidDataType("T_ROB1",
"MyModule", "processdata");
UserDefined processdata = new UserDefined(rdt);
NOTE!
If the module where the RECORD is defined is configured as -Shared you only provide the name of the data type as argument, like this: rdt = this.controller.Rapid.GetRapidDataType("processdata");
Reading UserDefined data
You can use a
UserDefined
object to read any kind of RECORD variable from the controller. The individual components of the RECORD are accessible using the
Components property and an index. Each
Component
can be read as a string.
VB:
C#:
Dim processdata As UserDefined = DirectCast(rd.Value, UserDefined)
Dim No1 As String = processdata.Components(0).ToString()
Dim No2 AS String = processdata.Components(1),ToString()
UserDefined processdata = (UserDefined) rd.Value; string no1 = processdata.Components[0].ToString(); string no2 = processdata.Components[1].ToString();
152
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.3.4. UserDefined data
Continued
Each individual string can then be used in a
FillFromString
method to convert the component into a specific data type, e.g.
RobTarget
or
ToolData
. See
IRapidData.FillFromString method on page 144
Writing to UserDefined data
If you want to modify
UserDefined
data and write it to the RECORD in the controller you must first read the
UserDefined
object and the apply new values using the
FillFromString
method. Then you perform a write operation using the
RapidData.Value
property.
VB: processdata.Components(0).FillFromString("[0,0,0]") processdata.Components(1).FillFromString("10") rd.Value = ud
C#: processdata.Components[0].FillFromString("[0,0,0]"); processdata.Components[1].FillFromString("10"); rd.Value = ud;
IRapidData.FillFromString method on page 144
Writing to RAPID data on page 223
for further information and code samples.
Implement your own struct representing a RECORD
This example shows how you can create your own .NET data type representing a RECORD in the controller instead of using the
UsefDefined
type.
Creating ProcessData type
VB:
Dim rdt As RapidDataType = Me.ARapid.GetRapidDataType("T_ROB1",
"MyModule", "processdata")
Dim p As ProcessData = New ProcessData(rdt) p.FillFromString(rd.Value.ToString())
C#
RapidDataType rdt = this.aRapid.GetRapidDataType("T_ROB1",
"MyModule", "processdata");
ProcessData p = new ProcessData(rdt); p.FillFromString(rd.Value.ToString());
3HAC028083-001 Revision: D
Continues on next page
153
5 Using the FlexPendant SDK
5.5.3.4. UserDefined data
Continued
Implementing ProcessData struct
This example shows how the new data type
ProcessData may be implemented. As you see, this is done by using a .NET struct and letting ProcessData wrap the
UserDefined
object.
The struct implementation should include a
FillFromString
and
ToString
method, i.e. inherit the
IRapidData
interface. Any properties and methods may also be implemented.
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; }
154
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.3.4. UserDefined data
Continued
} public int StepOne
{ get
{
} set
{ int res =
Convert.ToInt32(IntData.Components[0].ToString())
; return res;
IntData.Components[0] = new Num(value);
}
}
}
Implementing IRapidData methods
This piece of code shows how the two
IRapidData
methods
ToString
and
FillFromString
can be implemented.
VB:
Public Sub FillFromString(ByVal newValue As String) Implements
ABB.Robotics.Controllers.RapidDomain.IRapidData.FillFromStr
ing
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();
}
NOTE! The
ToString
method has to use the
Overrides
keyword in Visual Basic and the override
keyword in C#.
3HAC028083-001 Revision: D
Continues on next page
155
5 Using the FlexPendant SDK
5.5.3.4. UserDefined data
Continued
Property implementation
Each item in the RECORD structure should have a corresponding property in the extended
.NET data type. The get and set methods have to implement the conversion from/to controller data type to .NET data type.
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;
}
}
156 3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.3.5. RAPID symbol search
5.5.3.5. RAPID symbol search
Overview
Most RAPID elements (variables, modules, tasks, records etc.) are members of a symbol table, in which their names are stored as part of a program tree structure.
It is possible to search this table and get a collection of
RapidSymbol
objects, each one including the RAPID object name, location and type.
SearchRapidSymbol method
The search must be configured carefully, due to the large amount of RAPID symbols in a system. To define a query you need to consider from where in the program tree the search should be performed, which symbols are of interest and what information you need for the symbols of interest.To enable search from different levels the
SearchRapidSymbol
method is a member of several different SDK classes, e.g.
Task
,
Module
and
Routine
. This example shows a search performed with
Task
as the starting point:
VB:
Dim RSCol As RapidSymbol()
RSCol = ATask.SearchRapidSymbol(SProp, "num", string.Empty)
C#:
RapidSymbol[] rsCol; rsCol = aTask.SearchRapidSymbol(sProp, "num", string.Empty);
The
SearchRapidSymbol
method has three arguments. The first argument, of data type
RapidSymbolSearchProperties
, is detailed in the next section. The second and third arguments are detailed in the following sections.
Search properties
The
RapidSymbolSearchProperties
type is rather complex and requires some knowledge about RAPID concepts.
It is used to specify search method, type of RAPID symbol to search for, whether the search should be recursive, whether the symbols are local and/or global and whether or not the search result should include only symbols currently used by a program. If a property is not valid for a particular symbol, it will just be discarded and will not exclude the symbol from the search result.
The table describes the different properties of
RapidSymbolSearchProperties
.
Property Description
SearchMethod Specifies the direction of the search, which can be
Block
(down) or
Scope
(up). Example: If the starting point of the search is a routine, a block-search will return the symbols declared within the routine, whereas a scope-search will return the symbols accessible from the routine.
3HAC028083-001 Revision: D
Continues on next page
157
5 Using the FlexPendant SDK
5.5.3.5. RAPID symbol search
Continued
Property
SymbolType
Recursive
GlobalRapidSymbol
LocalRapidSymbol
IsInUse
Description
Specifies which RAPID type(s) you want to search for. The
SymbolTypes
enumeration includes
Constant
,
Variable
,
Persistent
,
Function
,
Procedure
,
Trap
,
Module
,
Task
,
Routine
,
RapidData
. etc. (
Routine
includes
Function
,
Procedure
and
Trap. RapidData
includes
Constant
,
Variable
and
Persistent
.)
For both block and scope search it is possible to choose if the search should stop at the next scope or block level or recursively continue until the root (or leaf) of the symbol table tree is reached.
Specifies whether global symbols should be included.
Specifies whether local symbols should be included.
Specifies whether only symbols in use by the loaded RAPID program should be searched.
Default instance
158
RapidSymbolSearchProperties
has a static method, which returns a default instance.
VB:
C#:
Dim SProp As RapidSymbolSearchProperties =
RapidSymbolSearchProperties.CreateDefault()
RapidSymbolSearchProperties sProp =
RapidSymbolSearchProperties.CreateDefault();
The default instance has the following values:.
Property Description
SearchMethod
SymbolType
Recursive
GlobalRapidSymbol
LocalRapidSymbol
IsInUse
SymbolSearchMethod.Block
SymbolTypes.NoSymbol
True
True
True
True
Using this instance you can specify the search properties of the search you want to perform.
Example:
VB:
C#:
SProp.SearchMethod = SymbolSearchMethod.Scope
SProp.SymbolType = SymbolTypes.Constant Or SymbolTypes.Persistent
SProp.Recursive = False sProp.SearchMethod = SymbolSearchMethod.Scope; sProp.SymbolType = SymbolTypes.Constant | SymbolTypes.Persistent
sProp.Recursive = false;
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.3.5. RAPID symbol search
Continued
NOTE!
The default instance has the property
SymbolType
set to
NoSymbol
, which means you need to specify it in order to perform a meaningful search.
NOTE!
The
SymbolType
property allows you to combine several types in the search. See the example above.
Data type argument
The second argument of the
SearchRapidSymbol
method is the RAPID data type written as a string. The data type should be written with small letters, e.g. “num”, “string” or
“robtarget”. It can also be specified as string.Empty
.
NOTE!
To search for a
UserDefined
data type the complete path to the module that holds the
RECORD definition must be passed, like this: result = tRob1.SearchRapidSymbol(sProp,"RAPID/T_ROB1/MyModule/
MyDataType", string.Empty);
However, if
MyModule
is configured as -Shared the system sees its data types as installed, and the task or module should not be included in the path result = tRob1.SearchRapidSymbol(sProp,"MyDataType", string.Empty);
Symbol name argument
The third argument is the name of the RAPID symbol. It can be specified as string.Empty
if the name of the symbol to retrieve is not known, or if the purpose is to search ALL “num” instances in the system for example.
Instead of the name of the RAPID symbol a regular expression can be used. The search mechanism will then match the pattern of the regular expression with the symbols in the symbol table. The regular expression string is not case sensitive
A regular expression is a powerful mechanism. It may consist of ordinary characters and meta characters. A meta character is an operator used to represent one or several ordinary characters, and the purpose is to extend the search.
Within a regular expression, all alphanumeric characters match themselves, i.e. the pattern
“abc” will only match a symbol named “abc”. To match all symbol names containing the character sequence “abc”, it is necessary to add some meta characters. The regular expression for this is “.*abc.*”.
The available meta character set is shown below:
Expression
.
^
[s]
[^s]
3HAC028083-001 Revision: D
Meaning
Any single character
Any symbol starting with
Any single character in the non-empty set s, where s is a sequence of characters. Ranges may be specified as c-c.
Any single character not in the set s.
Continues on next page
159
5 Using the FlexPendant SDK
5.5.3.5. RAPID symbol search
Continued
Expression
r* r+ r?
(r) r | r’
.*
Meaning
Zero or more occurrences of the regular expression r.
One or more occurrences of the regular expression r.
Zero or one occurrence of the regular expression r.
The regular expression r. Used for separate that regular expression from another.
The regular expressions r or r’.
Any character sequence (zero, one or several characters).
Example 1
"^c.*"
Returns all symbols starting with c or C.
Example 2
"^reg[1-3]"
Returns reg1, Reg1, REG1, reg2, Reg2, REG2, reg3, Reg3 and REG3.
Example 3
"^c.*|^reg[1,2]"
Returns all symbols starting with c or C as well as reg1, Reg1, REG1, reg2, Reg2 and REG2.
SearchRapidSymbol example
This example searches for VAR, PERS or CONST num data in a task and its modules. The search is limited to globally declared symbols. By default the search method is
Block
, so it does not have to be set.
VB:
Dim SProp As RapidSymbolSearchProperties =
RapidSymbolSearchProperties.CreateDefault()
SProp.SymbolTypes = SymbolTypes.RapidData
SProp.LocalRapidSymbol = False
Dim RSCol As RapidSymbol()
RSCol = ATask.SearchRapidSymbol(SProp, "num", string.Empty)
C#:
RapidSymbolSearchProperties sProp =
RapidSymbolSearchProperties.CreateDefault(); sProp.SymbolType = SymbolTypes.RapidData; sProp.LocalRapidSymbol = false;
RapidSymbol[] rsCol; rsCol = aTask.SearchRapidSymbol(sProp, "num", string.Empty);
160
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.3.5. RAPID symbol search
Continued
Search for UserDefined RAPID data - example
In this example a user defined RECORD data type (“mydata”) is declared in a module
(“myModule”). Assuming that the end-user can declare and use data of this data type in any program module, the search method must be Block (default). A search for all “mydata” instances may look like this:
VB:
C#:
Dim SProp As RapidSymbolSearchProperties =
RapidSymbolSearchProperties.CreateDefault()
SProp.SymbolType = SymbolTypes.RapidData
Dim RSCol As RapidSymbol()
RSCol = ATask.SearchRapidSymbol(SProp, "RAPID/T_ROB1/myModule/ mydata", string.Empty)
RapidSymbolSearchProperties sProp =
RapidSymbolSearchProperties.CreateDefault(); sProp.SymbolType = SymbolTypes.RapidData;
RapidSymbol[] rsCol; rsCol = aTask.SearchRapidSymbol(sProp, "RAPID/T_ROB1/myModule/ mydata", string.Empty);
NOTE!
If myModule is configured as -Shared and all myData instances are declared in myModule the search method must be set to
Scope
and the
SearchRapidSymbol
call should look like this: rsCol = aTask.SearchRapidSymbol(sProp, "mydata", string.Empty);
3HAC028083-001 Revision: D 161
5 Using the FlexPendant SDK
5.5.3.6. RAPID execution
5.5.3.6. RAPID execution
Start and Stop RAPID programs
You can start and stop RAPID execution using
Rapid
.
Start
and
Stop
methods. A
StartResult
from the
Start
method returns the result of the call. Start arguments can be used.
RegainMode
defines how the mechanical unit should handle path status at start.
ExecutionMode
specifies if the program should run continuously, step backward or go to the next Move instruction etc.
The
Stop
method can include a
StopMode
argument, specifying when the program should stop (after current cycle, after completed instruction or immediately).
VB:
AController.Rapid.Start(RegainMode.Regain,
ExecutionMode.Continous)
.....
AController.Rapid.Stop(StopMode.Instruction)
C#: aController.Rapid.Start(RegainMode.Regain,
ExecutionMode.Continous);
.....
aController.Rapid.Stop(StopMode.Instruction);
NOTE!
It is also possible to start a service routine or an ordinary routine without any parameters as if it were a service routine. See
Task.CallRoutine
and
Task.CancelRoutine
in the FP
SDK Reference Help for detailed information along with code samples.
RAPID execution change event
It is possible to subscribe to events that occur when a RAPID program starts to execute and when it stops. This is done on the
Rapid
property of the
Controller
object, like this:
VB:
AddHandler AController.Rapid.ExecutionStatusChanged, AddressOf
UpdateUI
C# aController.Rapid.ExecutionStatusChanged += new
ExecutionStatusChangedEventHandler(UpdateUI);
Letting the user know that RAPID data has changed on page 224
code example on how write the event handlers needed to update the GUI due to a controller event.
ResetProgramPointer method
The
ResetProgramPointer
method resets the program pointers of all tasks and sets them to the main entry point of the respective task.
VB:
AController.Rapid.ResetProgramPointer()
162
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.3.6. RAPID execution
Continued
C#: aController.Rapid.ResetProgramPointer();
NOTE!
It is also possible to set the program pointer to a specified routine, row or position. See
Task.SetProgramPointer
in the FP SDK Reference for information along with code samples.
3HAC028083-001 Revision: D 163
5 Using the FlexPendant SDK
5.5.3.7. Modifying modules and programs
5.5.3.7. Modifying modules and programs
Overview
Using the
Task
object it is possible to load and save programs and individual modules. You can also unload programs, get the position of the motion pointer (MP) and the program pointer (PP) as well as modify a robot position.
Load modules and programs
To load a module or program file you need the path to the file in the file system of the controller. When the file is loaded into memory the
RapidLoadMode
enumeration argument,
Add
or
Replace
, specifies whether or not it should replace old modules or programs.
If the file extension is not a valid module (mod or sys) or program (pgf) extension an
ArgumentException
is thrown.
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;
}
Save and unload RAPID program
You can save a program using the
SaveProgramToFile
method and unload it using the
DeleteProgram
method. These methods save and unload all modules in the task.
VB:
Dim TaskCol As Task() = AController.Rapid.GetTasks()
Dim AnObject As Object
For Each AnObject in TaskCol
ATask = DirectCast(AnObject, Task)
ATask.ProgramName = ATask.Name
ATask.SaveProgramToFile(SaveDir)
ATask.DeleteProgram()
Next
164
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.3.7. Modifying modules and programs
Continued
C#:
Task[] taskCol = aController.Rapid.GetTasks(); foreach (Task aTask in taskCol)
{ aTask.PrograamName = aTask.Name; aTask.SaveProgramToFile(saveDir); aTask.DeleteProgram();
}
Save module
You can save a module by using the
Module.SaveToFile
method. As argument you use a path to the controller file system.
VB:
AModule.SaveToFile(AFilePath)
C# aModule.SaveToFile(aFilePath);
ProgramPointer and MotionPointer
The Task.
ProgramPointer
property returns the current location of the program pointer
(module, routine and row number), i.e. where the program is currently executing. The same functionality is available for motion pointer by using the
MotionPointer
property.
VB:
Dim APP As ProgramPointer = ATask.ProgramPointer
If Not APP = ProgramPointer.Empty Then
Dim AStartRow As Integer = APP.Start.Row
.....
C#:
ProgramPointer pp = aTask.ProgramPointer; if (pp != ProgramPointer.Empty)
{ int aStartRow = pp.Start.Row;
.....
}
ModifyPosition method
Using the ModifyPosition method of the
Task
object you can modify the position of a
RobTarget
instance in the currently loaded program. As arguments you supply a module
Name
as well as a
TextRange
object. The first
RobTarget
within the text range specified by the
TextRange
object will be changed using the current TCP of the active mechanical unit.
VB:
Me.ATask.ModifyPosition(AModule, ATextRange)
C#:
TIP!
this.ATask.ModifyPosition(aModule, aTextRange)
Learn more about
Task
methods and properties in the FP SDK Reference.
3HAC028083-001 Revision: D 165
5 Using the FlexPendant SDK
5.5.4. IO system domain
5.5.4. IO system domain
Overview
A robot system uses input and output signals to control processes. Signals can be of digital, analog or group signal type. Such IO signals are accessible using the SDK.
Signal changes in the robot system are often significant, and there are many scenarios where end-users of the system need notification of signal changes.
Accessing signals
Accessing signals is done through the
Controller
object and its property
IOSystem
, which represents the IO signal space in the robot controller.
To access a signal you need the system name of the signal. The object that is returned from the
IOSystem
.
GetSignal
method is of type
Signal
.
VB:
Dim Signal1 As Signal = AController.IOSystem.GetSignal("signal name")
C#:
Signal signal1 = aController.IOSystem.GetSignal("signal name");
The returned
Signal
object has to be typecast to digital, analog or group signal. This example shows a how a signal of type
DigitalSignal
is created:
VB:
Dim DISig As DigitalSignal = DirectCast(Signal1, DigitalSignal)
C#:
DigitalSignal diSig = (DigitalSignal) signal1;
This example shows a how an
AnalogSignal
is created:
VB:
Dim AISig As AnalogSignal = DirectCast(Signal1, AnalogSignal)
C#:
AnalogSignal aiSig = (AnalogSignal) signal1;
This example shows a how a
GroupSignal
is created:
VB:
Dim GISig As GroupSignal = DirectCast(Signal1, GroupSignal)
C#:
GroupSignal giSig = (GroupSignal) signal1;
166
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.4. IO system domain
Continued
NOTE!
Remember to call the
Dispose
method of the signal when it should no longer be used.
Getting signals using SignalFilter
Instead of just getting one signal at a time you can use a filter and get a signal collection. Some of the
SignalFilter
flags are mutually exclusive, e.g.
SignalFilter.Analog
and
SignalFilter.Digital
. Others are inclusive, e.g.
SignalFilter.Digital
and
SignalFilter.Input
. You can combine the filter flags using the “|” character in C# and the
Or
operator in VB:
VB:
C#:
Dim ASigFilter As SignalFilter = SignalFilter.Digital Or
SignalFilter.Input
Dim Signals As SignalCollection =
AController.IOSystem.GetSignals(ASigFilter)
SignalFilter aSigFilter = SignalFilter.Digital |
SignalFilter.Input;
SignalCollection signals = aController.IOSystem.GetSignals(aSigFilter);
This piece of code iterates the signal collection and adds all signals to a
ListView
control.
The list has three columns displaying signal name, type and value:
VB:
For Each ASignal As Signal In Signals
Item = New ListViewItem(ASignal.Name)
Item.SubItems.Add(ASignal.Type.ToString())
Item.SubItems.Add(ASignal.Value.ToString())
Me.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()); this.listView1.Items.Add(item);
}
If the signal objects are no longer needed they should be disposed of:
VB:
For Each ASignal As Signal In Signals
ASignal.Dispose()
Next
3HAC028083-001 Revision: D
Continues on next page
167
5 Using the FlexPendant SDK
5.5.4. IO system domain
Continued
C#: foreach(Signal signal in signals)
{ signal.Dispose();
}
Reading IO signal values
These examples show how to read a digital and an analog signal.
Digital signal
This piece of code reads the digital signal DO1 and checks a checkbox if the signal value is
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
EndIf
C#:
Signal sig = aController.IOSystem.GetSignal("DO1");
DigitalSignal digitalSig = (DigitalSignal)sig; int val = digitalSig.Get(); if (val == 1)
{ this.checkBox1.Checked = true;
}
Analog signal
This piece of code reads the value of the analog signal AO1 and displays it in a textbox:
VB:
Dim Sig As Signal = AController.IOSystem.GetSignal("AO1")
Dim AnalogSig As AnalogSignal = DirectCast(Sig, AnalogSignal)
Dim AnalogSigVal As Single = AnalogSig.Value
Me.TextBox1.Text = AnalogSigVal.ToString()
C#:
Signal sig = aController.IOSystem.GetSignal("AO1");
AnalogSignal analogSig = (AnalogSignal)sig; float analogSigVal = analogSig.Value; this.textBox1.Text = analogSigVal.ToString();
168
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.4. IO system domain
Continued
Writing IO signal values
In this example, new values for the IO signals that were retrieved in the previous example are written to the controller.
NOTE!
In manual mode a signal value can be modified only if the Access Level of the signal is ALL.
If not, the controller has to be in auto mode.
Digital signal
This piece of code changes the value of a digital signal in the controller when the user checks/ unchecks a checkbox:
VB:
Private Sub CheckBox1_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles CheckBox1.Click
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();
}
}
NOTE! You can also set the value using the
Value
property.
Analog signal
This piece of code writes the value entered in a text box to the analog signal AO1. The value is converted from string to a float before it is written to the controller:
VB:
Dim AnalogSigVal As Single = Convert.ToSingle(Me.TextBox1.Text)
AnalogSig.Value = AnalogSigVal
3HAC028083-001 Revision: D
Continues on next page
169
5 Using the FlexPendant SDK
5.5.4. IO system domain
Continued
C#: float analogSigVal = Convert.ToSingle(this.textBox1.Text); analogSig.Value = analogSigVal;
Listening to signal changes
Once a
Signal
object is available it is possible to add a subscription to its Changed event, which is triggered at a signal change such as changed value, changed simulated status or changed signal quality.
Visual Basic
Friend WithEvents AISig As AnalogSignal
...
AddHandler AISig.Changed, AddressOf AISig_Changed
...
Private Sub AISig_Changed(sender As Object, e As
SignalChangeEventArgs) Handles AISig.Changed
End Sub
C# this.aiSig.Changed +=new SignalChangeHandler(aiSig_Changed);
NOTE! The event handler skeleton is auto generated using the Tab key twice after “+=” in the above statement: private void aiSig_Changed(object sender, SignalChangeEventArgs e)
{ }
Start and stop subscriptions
It is recommended that you activate and deactivate subscriptions to the
Changed
event if these are not necessary throughout the lifetime of the application:
VB:
AddHandler AISig.Changed, AddressOf AISig_Changed
RemoveHandler AISig.Changed, AddressOf AISig_Changed
C#: this.aiSig.Changed += new SignalChangeHandler(aiSig_Changed); this.aiSig.Changed -= new SignalChangeHandler(aiSig_Changed);
170
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.4. IO system domain
Continued
Avoiding threading conflicts
It is important to keep in mind that all controller events use their own threads, which are different from the application GUI thread. This can cause problems if you want to display signal changes in the application GUI.
If an update of the user interface is not necessary, you do not need to take any special action, but can execute the event handler on the event thread. If, however, you need to show to the user that the signal has changed you should use the
Invoke
method. It forces execution to the window control thread and thus provides a solution to potential threading conflicts.
VB:
Me.Invoke(New ABB.Robotics.Controllers.IOSystemDomain.
SignalChangedEventHandler(AddressOf UpdateUI), New Object()
{sender, e})
C#: this.Invoke(new ABB.Robotics.Controllers.IOSystemDomain.
SignalChangedEventHandler(this.UpdateUI), new Object[]
{sender, e});
See
Controller events and threads on page 67
Finding out the new value
The
SignalChangedEventArgs
object has a
NewSignalState
property, which has information about signal value, signal quality and whether the signal is simulated or not:
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, SignalChangedEventArgs e)
{
SignalState state = e.NewSignalState;
....
float val = state.Value
this.textBox1.Text = val.ToString()
}
NOTE!
Do not count on receiving an initial event when setting up the subscription. To get initial information about the value of a signal you should read it using the
Value
property.
NOTE!
Make sure the subscription is removed before you dispose of the signal.
3HAC028083-001 Revision: D 171
5 Using the FlexPendant SDK
5.5.5. Event log domain
5.5.5. Event log domain
Overview
Event log messages may contain information about controller status, RAPID execution, the running processes of the controller etc.
Using the SDK it is possible to either read messages in the queue or to use an event handler that will receive a copy of each new log message. An event log message contains queue type, event type, event time, event title and message.
Access the controller event log
You access the event log domain through the
Controller
property
EventLog
.
VB:
Private Log As EventLog = AController.EventLog
C#: private EventLog log = aController.EventLog;
Access event log categories
All event log messages are organized into categories. To search for an individual message you have to know what category it belongs to. The enumeration type,
CategoryType
, defines all available categories. You can get a category either by using the method
GetCategory
or by using the
Categories
property, which is an array of all available categories.
VB:
Dim Cat As EventLogCategory
Cat = Log.GetCategory(CategoryType.Program) or
C#:
Cat = Log.Categories(4)
EventLogCategory cat; cat = log.GetCategory(CategoryType.Program); or cat = log.GetCategory[4];
NOTE!
The
EventLogCategory
should be disposed of when it is no longer used.
Access event log messages
To access a message you use the
Messages
property of the
Category
object. A collection of messages is returned. The collection implements the
ICollection
and
IEnumerable interfaces , which means you can use the common operations for collections. Access is done either using an index or by iterating using foreach
.
VB:
Dim Msg As EventLogMessage = Cat.Messages(1)
172
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.5. Event log domain
Continued
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 msg in cat.Messages)
{ this.textBox1.Text = msg.Title;
.....
}
MessageWritten event
It is possible to add an event handler that is notified when a new messages is written to the controller event log. This is done by subscribing to the EventLog event
MessageWritten
.
The event argument is of type
MessageWrittenEventArgs
and has a
Message
property, which holds the latest event log message.
VB:
Private Sub Log_MessageWritten(sender As Object, e As
MessageWrittenEventArgs) Handles Log.MessageWritten
Dim Msg As EventLogMessage = e.Message
End Sub
C#: private void log_MessageWritten(object sender,
MessageWrittenEventArgs e)
{
EventLogMessage msg = e.Message;
}
NOTE!
If the application user interface needs to be updated as a result of the event, you must delegate this job to the GUI thread using the
Invoke
method. See
further information and code samples.
3HAC028083-001 Revision: D 173
5 Using the FlexPendant SDK
5.5.6. Motion domain
5.5.6. Motion domain
Overview
The
MotionDomain
namespace lets you access the mechanical units of the robot system.
Using a
MotionSystem
object you can send jogging commands to an mechanical unit and get or set the incremental jogging mode. Using a
MechanicalUnit
object you can get a lot of information about the mechanical units of the robot system.
You can also subscribe to changes of the mechanical unit, e.g. changed tool, work object, coordinated system, motion mode or incremental step size.
MotionSystem object
You access the motion system by using a the
Controller
property
MotionSystem
.
VB:
Private AMotionSystem As MotionSystem
AMotionSystem = AController.MotionSystem
C# private MotionSystem aMotionSystem; aMotionSystem = aController.MotionSystem;
Accessing Mechanical units
The mechanical units can be of different types, e.g. a robot with a TCP, a multiple axes manipulator or a single axis unit. Mechanical units are available through the
MotionSystem object. If only the active mechanical unit is of interest you may use the method
GetActiveMechanicalUnit
.
VB:
C#:
Dim AMechCol As MechanicalUnitCollection =
AController.MotionSystem.GetMechanicalUnits()
Dim AMechUnit As MechanicalUnit =
AController.MotionSystem.GetActiveMechanicalUnit();
MechanicalUnitCollection aMechCol = aController.MotionSystem.GetMechanicalUnits();
MechanicalUnit aMechUnit = aController.MotionSystem.GetActiveMechanicalUnit();
Jogging
174
It is possible to jog the active mechanical unit using the
SetJoggingCmd
method and the calls
JoggingStart
and
JoggingStop
. Depending on the selected
MotionMode
and
IncrementalMode
different joints and speeds are configured.
VB:
AController.MotionSystem.JoggingStop()
AMechUnit.MotionMode = MotionModeType.Linear
AController.MotionSystem.IncrementalMode =
IncrementalModeType.Small
AController.MotionSystem.SetJoggingCmd(-50, 50, 0)
AController.MotionSystem.JoggingStart()
Continues on next page
3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.6. Motion domain
Continued
C#: aController.MotionSystem.JoggingStop(); aMechUnit.MotionMode = MotionModeType.Linear; aController.MotionSystem.IncrementalMode =
IncrementalModeType.Small; aController.MotionSystem.SetJoggingCmd(-50, 50, 0); aController.MotionSystem.JoggingStart();
Mechanical unit properties and methods
There are numerous properties available for the mechanical unit, e.g.
Name,Model,
NumberOfAxes,SerialNumber,CoordinateSystem
,
MotionMode
,
IsCalibrated
,
Tool
and
WorkObject
etc. It is also possible to get the current position of a mechanical unit as a
RobTarget
or
JointTarget
.
VB:
Dim ARobTarget As RobTarget =
AController.MotionSystem.GetActiveMechanicalUnit.GetPositio
n(CoordinateSystemType.World)
Dim AJointTarget As JointTarget =
AController.MotionSystem.ActiveMechanicalUnit.GetPosition()
C#:
RobTarget aRobTarget = aController.MotionSystem.GetActiveMechanicalUnit.GetPositio
n(CoordinateSystemType.World);
JointTarget aJointTarget = aController.MotionSystem.ActiveMechanicalUnit.GetPosition()
;
DataChanged event
By subscribing to the
DataChanged
event of the
MechanicalUnit
object, you will be notified when a change of tool, work object, coordinated system, motion mode or incremental step size occurs.
VB:
AddHandler AMechUnit.DataChanged, AddressOf AMech_DataChanged
......
Private Sub AMech_DataChanged(sender As Object, e As
MechanicalUnitDataEventArgs)
Select e.Reason
Case MechanicalUnitDataChangeReason.Tool
ChangeOfTool(DirectCast(sender, MechanicalUnit))
Case MechanicalUnitDataChangeReason.WorkObject
......
End Select
End Sub
3HAC028083-001 Revision: D
Continues on next page
175
5 Using the FlexPendant SDK
5.5.6. Motion domain
Continued
C#: aMechUnit.DataChanged += new
MechanicalUnitDataEventHandler(aMech_DataChanged);
.....
private void aMech_DataChanged(object sender,
MechanicalUnitDataEventArgs e) { switch (e.Reason) { case MechanicalUnitDataChangeReason.Tool:
ChangeOfTool((MechanicalUnit)sender) case MechanicalUnitDataChangeReason.WorkObject:
......
}
}
TIP!
Read more about the classes, methods and properties available in the
MotionDomain
in the
FP SDK Reference help.
176 3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.7. File system domain
5.5.7. File system domain
Overview
Using the FlexPendant SDK FileSystemDomain you can create, save, load, rename and delete files on the controller. You can also create and delete directories.
Accessing files and directories
You access the file system domain through the
Controller
object property
FileSystem
.
VB:
Private AFileSystem As FileSystem = AController.FileSystem
C#:
FileSystem aFileSystem = aController.FileSystem;
Controller and FlexPendant file system
You can find and set the remote directory on the controller and the local directory on the
FlexPendant device by using the
RemoteDirectory
and
LocalDirectory
properties.
VB:
C#:
Dim RemoteDir As String = AController.FileSystem.RemoteDirectory
Dim LocalDir As String = AController.FileSystem.LocalDirectory
string remoteDir = aController.FileSystem.RemoteDirectory; string localDir = aController.FileSystem.LocalDirectory;
Loading controller files
You can load a file from the controller to the FlexPendant using the
GetFile
method. An exception is thrown if the operation fails. The arguments are complete paths including filenames.
VB:
AController.FileSystem.FileSystem.GetFile(RemoteFilePath,
LocalFilePath)
C#: aController.FileSystem.GetFile(remoteFilePath, localFilePath);
Saving files
You can save a file to the controller file system by using the
PutFile
method. An exception is thrown if the operation fails. The arguments are complete paths including filenames.
VB:
AController.FileSystem.PutFile(LocalFilePath, RemoteFilePath)
C#: aController.FileSystem.PutFile(localFilePath, remoteFilePath);
3HAC028083-001 Revision: D
Continues on next page
177
5 Using the FlexPendant SDK
5.5.7. File system domain
Continued
Getting multiple files and directories
The
FileSystem
class has a method called
GetFilesAndDirectories
. It can be used to retrieve an array of
ControllerFileSystemInfo
objects with information about individual files and directories. The
ControllerFileSystemInfo
object can then be cast to either a
ControllerFileInfo
object or a
ControllerDirectoryInfo
object.
This example uses search pattern to limit the search.
VB:
Dim AnArray As ControllerFileSystemInfo()
Dim info As ControllerFileSystemInfo
AnArray = AController.FileSystem.GetFilesAndDirectories("search pattern")
Dim I As Integer
For I = 0 To array.Length -1 info = AnArray(I)
......
Next
C#:
ControllerFileSystemInfo[] anArray;
ControllerFileSystemInfo info; anArray = aController.FileSystem.GetFilesAndDirectories("search pattern"); for (int i=0;i<anArray.Length;i++) { info = anArray[i];
......
}
Using search patterns
As seen in the example above, you can use search patterns to locate files and directories using the
GetFilesAndDirectories
method. The matching process uses the Wildcard pattern matching of Visual Studio. This is a brief summary:
Character in pattern
?
*
#
[charlist]
[!charlist]
Matches in string
Any single character
Zero or more characters
Any single digit (0–9)
Any single character in charlist
Any single character not in charlist
TIP!
Read more about the classes, methods and properties available in the
FileSystemDomain in the FP SDK Reference help.
178 3HAC028083-001 Revision: D
5 Using the FlexPendant SDK
5.5.8. System info domain
5.5.8. System info domain
Overview
The
SystemInfoDomain
provides information about the active robot system. This is mainly done through the static methods and properties of the
SystemInfo
class:
5.8.1_1
SystemInfo class
The functionality of the
SystemInfoDomain
is accessed by calling the static methods of the
SystemInfo
class.This is how to retrieve the path in the controller file system to the release
(ROBOTWARE) directory of the active system.
Example: string rWDir =
ABB.Robotics.Controllers.SystemInfoDomain.SystemInfo.Releas
ePath
Likewise, the path to the active system directory can be retrieved: string sysDir =
ABB.Robotics.Controllers.SystemInfoDomain.SystemInfo.System
Path
3HAC028083-001 Revision: D
Continues on next page
179
5 Using the FlexPendant SDK
5.5.8. System info domain
Continued
System options
Using the
SystemInfo.SystemOptions
property you can retrieve the system options of the currently active robot system. The result is an array of
SystemOption
objects. If you list the
Name
property of these objects you will get the same result as shown in the SystemBuilder of RobotStudio, e.g:
5.5.8_2
You can retrieve sub options of a system option by using the
SystemOption.SubOptions
property.
Additional options
Using the
SystemInfo.AdditionalOptions
property you can find out which additional options are installed in the robot system. The result is an array of
AdditionalOption objects. The
AdditionalOption.Path
property returns the path to the installation directory of the additional option.
The following
AdditionalOption
properties are available:
•
KeyString
•
Name
• Path
•
Type
• VersionInfo
NOTE!
You can find out more about the
SystemInfoDomain
in the FP SDK Reference, which also provides you with code examples.
180 3HAC028083-001 Revision: D
Download
Advertisement
Key features
Develop custom operator interfaces
FlexPendant SDK
PC SDK
Visual Studio integration
.NET programming
Virtual IRC5
Frequently asked questions
Robot Application Builder (RAB) is a software tool, which enables programmers to develop customized operator interfaces for the IRC5 robot controller.
The supported operating systems are Microsoft Windows XP + SP2 or Windows Vista + SP1.
The supported versions are Visual Studio 2005 and Visual Studio 2008.
The supported programming languages are C# and Visual Basic.NET for FlexPendant applications. For PC applications, any of the .NET languages should work, however, ABB support is only offered for Visual Basic and C#.