URCap Key Methods and Principles

This document explains the integration of URCaps into PolyScope through specific interfaces and methods for various functionality types, such as Program Nodes, Installation Nodes, and Toolbars. URCaps operate as child processes of PolyScope, registering and interacting during startup and user interactions. These functionalities are often referred to as services. For instance, a gripper URCap might include services for configuring, opening, and closing the gripper, as well as a toolbar for live control. PolyScope detects URCaps at startup, calling the Activator’s start() method to register services, and the stop() method when shutting down. The Service sets static properties and methods for the UI and node contributions. This guide provides a concise summary of key methods and their purposes for Swing-based implementations

Principles of URCaps Integration

When a service is needed, such as for a Program Node, PolyScope calls methods in the Service to create the node, generating a User Interface (UI) and a Contribution. The UI is a single instance regardless of how many nodes are inserted. It contains visual elements and interacts with the Contribution to change settings. The Contribution, a new instance for each active node, contains the logic and uses a DataModel to store configurations. The UI reports user actions to the Contribution, which updates the DataModel and generates URScript during program execution. Interaction primarily occurs between the UI and Contribution.

Program Node Integration

Swing Program Node

Swing Program Node Service

Java Swing Program Node Service must implement the following methods:

getId(): Returns a string that its the unique ID for the node

  • Aguments: void

  • Returns: string.

return "myNodeType";

configureContribution(): Configures the node’s properties. The ContributionConfiguration-object can be altered, by calling the associated methods.

  • Arguments: ContributionConfiguration configuration

  • Returns: void

configuration.setChildrenAllowed(false); 
configuration.setUserInsertable(false);

getTitle(): Provides the node’s name in the Structure overview.

  • Arguments: Locale locale

  • Returns: String

if ("de".equals(locale.getLanguage())) {
    return "Greifer Öffnen";
} else {
    return "Gripper Open";
}

createView(): Creates and return the node’s view. The ViewAPIProvider that provided as argument will typically be forwarded to the View-class, as it is required for e.g. creating keyboards on textfields. There is only a singular instance of the View, and its created the first time this type of node is inserted by user or loaded in a program.

  • Arguments: ViewAPIProvider apiProvider

  • Returns: V (a generic type of the SwingProgramNodeView)

return new MyProgramNodeView(apiProvider);

createNode(): Creates and returns the a new instance of the Contribution. Contrary to the view, there will be a new instance of the Contribution every time a new node is needed.

  • Arguments: ProgramAPIProvider apiProvider, V view, DataModel model, CreationContext context

  • Returns: C (a generic type of the ProgramNodeContribution)

return new MyProgramNodeContribution(apiProvider, view, model, context);

Swing Program Node View

Swing Program Node View must implement:

buildUI(): Builds the node’s user interface.

When a View is created, the buildUI()-method is called. The method provides a JPanel as an argument. This JPanel is the panel that will be shown to the user in PolyScope. The JPanel has been given the dimensions, of the actual space available in PolyScope, and during the buildUI()-call, this panel should be populated with the UI elements desired to display to the user. Upon the return of this call, the provided JPanel will be shown to the user.

Another argument is the ContributionProvider. Since there can be multiple instances of the Contribution, but only 1 instance of View, the ContributionProvider will provide access to the active Contribution, when the user interacts with the node. Calling “provider.get()” will return the instance of the active ProgramNodeContribution.

  • Arguments: JPanel panel, ContributionProvider provider

  • Returns: void

// Example: Populate the provided JPanel with UI elements

Program Node Contribution

A new instance of the ProgramNodeContribution is returned every time the user inserts a new node, or an existing node is loaded. The ProgramNodeContribution-interface is unchanged regardless of the UI being Swing or HTML based, however the way of interacting with either implementation may vary.

Program Node Contribution methods include:

openView(): Populates the unique instace of the UI with node-specific settings. This call is used to read the active values in the DataModel, and update these values to be active in the UI.

  • Arguments: void

  • Returns: void

// Read DataModel values and update UI

closeView(): Handles when the user leaves the node’s UI.

  • Arguments: void

  • Returns: void

// Stop any running tasks started in openView()

isDefined(): Indicates if the node has all necessary data configured. This method is called almost anytime anything changes anywhere in the program. This means that this call will happen frequently, even if this node is not in focus. The code executed in this callback must be very lean and should only depend on DataModel values. This method should not check whether external hardware is connected, only whether more data needs to be configured in the node.

  • Arguments: void

  • Returns: Boolean

return model.get("configured") != null;

getTitle(): Returns the node’s name in the program tree based on the current configuration, in contrast with the getTitle() method in the Service, which returns the static name of the node in the list of available nodes.

  • Arguments: void

  • Returns: String

return "Gripper Move: 35 mm";

generateScript(): Generates URScript for the node.

Ultimately, the purpose of a Program Node is to generate some URScript, which will execute when the program is playing. The generateScript()-method is where this URScript should be generated. Typically, the generated script, should only depend on settings from the DataModel or static values.

The script should be created using the ScriptWriter-object. E.g. by appending script lines to the ScriptWriter as “writer.appendLine(“set_digital_out(0, True)”);” or using the custom URScript calls “writer.assign(“myVariable”, “42”)”. Refer to the URScript Manual for the syntax of URScript.

The URScript generated by generateScript() is appended to the overall program, at the relative location of the node in the program.

  • Arguments: ScriptWriter writer

  • Returns: void

    writer.appendLine("set_digital_out(0, True)");

Installation Node Integration

Swing Installation Node Service

Swing Installation Node Service

Swing Installation Node Service must implement:

getTitle(): Provides the name of the Installation Node.

return "My Installation";

configureContribution(): Configures the installation node.

  • Arguments: ContributionConfiguration configuration

  • Returns: void

// Currently left blank

createView(): Creates the view for the Installation Node.

While a program node may exist in multiple instances at the same time, the relationship between SwingInstallationNodeView and InstallationNodeContribution is always 1:1. There will only be exactly one View-instance and exactly one Contribution-instance at the same time.

Since the Installation Node will always be a part of a loaded installation, the createView()-method is called shortly after the service is registered. This method call should return a new instance of the View-class. The ViewAPIProvider is given as an argument. The ViewAPIProvider will typically be forwarded to the View-class, as it is required for e.g. creating keyboards on textfields.

The ViewAPIProvider can also be used to get the SystemAPI, which can be used to check the software version of the robot. This is useful to create a versioned user experience, based on whether the URCap is installed on an e-Series robot (PolyScope 5.x+) or a CB3 robot (PolyScope 3.3+).

  • Arguments: ViewAPIProvider apiProvider

  • Returns: V (a generic type of the SwingInstallationNodeView)

  return new MyInstallationNodeView(apiProvider);

createInstallationNode(): Creates the node’s contribution.

The createNode()-method should return a new instance of the Contribution. While there is only a singular instance of the View, a new instance of the Installation Node Contribution may be created, when the Installation on the robot is switched. This can happen if a new installation is created, or an existing installation file is loaded.

The arguments should as a rule of thumb be forwarded to the Contribution class, to use at its disposal. The InstallationAPIProvider gives the contribution access to PolyScope API’s that are relevant for installation nodes. The V-argument is the returned object of the createView()-method, and allows the Contribution to interact with the View.

The DataModel is what the Contribution can use, to store the settings and configuration of the node, done by the user. If the node is newly inserted, the DataModel will be blank, but if the node is loaded (e.g. as part of an installation file) the DataModel may already contain the configuration data for the node. The CreationContext can be used by the Contribution to check whether the creation of itself is a result of a newly inserted node, or whether the node is loaded.

  • Arguments: InstallationAPIProvider apiProvider, V view, DataModel model, CreationContext context

  • Returns: C (a generic type of the InstallationNodeContribution)

return new MyInstallationNodeContribution(apiProvider, view, model, context);

Swing Installation Node View

Swing Installation Node View must implement:

buildUI(): When a View is created, the buildUI()-method is called. The method provides a JPanel as an argument. This JPanel is the panel that will be shown to the user in PolyScope. The JPanel has been given the dimensions, of the actual space available in PolyScope, and during the buildUI()-call, this panel should be populated with the UI elements desired to display to the user. Upon the return of this call, the provided JPanel will be shown to the user.

The loaded instance of the InstallationNodeContribution is provided as an argument, and the View-class may use this to interact with the Contribution, when the user performs actions in the UI.

  • Arguments: JPanel panel, C contribution (a generic type of the InstallationNodeContribution)

  • Returns: void

// Populate the provided JPanel with UI elements

Installation Node Contribution

Installation Node Contribution methods include:

openView(): Populates UI with node-specific settings. This call is used to read the active values in the DataModel, and update these values to be active in the UI.

  • Arguments: void

  • Returns: void

// Read DataModel values and update UI

closeView(): Handles when the user leaves the node’s UI.

  • Arguments: void

  • Returns: void

// Stop any running tasks started in openView()

generateScript(): Generates URScript for the node.

When an Installation Node is contributing URScript to the overall program, this will be used as a preamble before the program node logic and URScript is added. This makes the Installation Node useful for initializing values or settings, or defining functions used later in the program by a program node.

Typically, the generated script, should only depend on settings from the DataModel or static values. The script should be created using the ScriptWriter-object. E.g. by appending script lines to the ScriptWriter as “writer.appendLine(“set_digital_out(0, True)”);” or using the custom URScript calls “writer.assign(“myVariable”, “42”)”. Refer to the URScript Manual for the syntax of URScript.

writer.appendLine("set_digital_out(0, True)");

Toolbar Integration

The toolbar differs from the Program Node and Installation Node, as it does not have any context to either a program or an installation, but is rather global for the robot. The Toolbar is mainly used for live control of external devices, or displaying runtime data to the use.

Swing Toolbar Integration

Swing Toolbar Service

Swing Toolbar Service must implement:

getIcon(): Returns the toolbar’s icon that allows user navigates between the active toolbars on the robot.

  • Arguments: void

  • Returns: Icon

return new ImageIcon(getClass().getResource("/icons/myToolbarIcon.png"));

configureContribution(): Configures the toolbar. The ToolbarConfiguration represents the configuration of toolbar. The ToolbarConfiguration -object can be altered, by calling the associated methods.

  • Arguments: ToolbarConfiguration configuration

  • Returns: void

configuration.setToolbarHeight(200);

createToolbar(): Creates and return the toolbar’s contribution instance. The argument ToolbarContext should be forwarded to the Contribution, as this may later be used to access relevant API’s and services for a toolbar.

  • Arguments: ToolbarContext context

  • Returns: SwingToolbarContribution

return new MyToolbarContribution(context);

Swing Toolbar Contribution

As the Toolbar does not have a context to the program or installation domains of the robot, the  SwingToolbarContribution serves as both the logical code and the UI which would be two separate classes for e.g. a Program Node.

The following methods must be implemented by the SwingToolbarContribution:

buildUI(): This method provides a JPanel as an argument. This JPanel is the panel that will be shown to the user in PolyScope. The JPanel has been given the dimensions, of the actual space available in PolyScope, and during the buildUI()-call, this panel should be populated with the UI elements desired to display to the user.

  • Arguments: JPanel panel

  • Returns: void

// Populate the provided JPanel with UI elements

openView(): Starts tasks when the toolbar is opened.

  • Arguments: void

  • Returns: void

// Start a timer to update values in the Toolbar

closeView(): Stops tasks when the toolbar is closed.

  • Arguments: void

  • Returns: void

// Stop any running tasks started in openView()