Smart Skills Contributions

Why Smart Skills?

As a part of a front-end contribution you can choose to contribute one or more smart skills. Smart skills are quick access behaviors that users can start and stop from the move drawer (depicted in the image below) to assist them in achieving a smoother and faster programming experience.

What is a Smart Skill?

The behavior that a smart skill exhibits is defined in URScript. This URScript has the same rights as any regular program. This means that you could e.g., ask your backend to execute specific tasks (through e.g., ROS2 or XML-RPC interfaces), move the robot, or control peripheral equipment directly, etc.

Types of behaviors

Smart skills can both be discrete and continuous.

  • Discrete smart skills are brief, well-defined actions with a clear beginning and end. This means that the smart skill automatically terminates without requiring user input to do so.

  • Continuous smart skills have no apparent beginning nor end. An example could be setting the robot in freedrive mode which would require the user to terminate.

How to add a Smart Skill to a Front-end Contribution?

If you have a URCap that does not contain a smart skill you can add one by following these steps:

1. Add the Folders and Files

Add a folder to your frontend where you store your smart skill(s), and add the smart skill behavior worker TS file to that folder. In our example we call our folder gripper-smart-skill and likewise for the behavior worker (it is not required that the folder and the behavior worker are named the same):

└─ src
   ├─ app
   │  ├─ app.module.ts
   │  └─ components
   │     ├─ gripper-program-node
   │     │  ├─ gripper-program-node.behavior.worker.ts
   │     │  ├─ gripper-program-node.component.html
   │     │  ├─ gripper-program-node.component.ts
   │     │  └─ gripper-program-node.node.ts
   │     └─ gripper-smart-skill
   │        └─ gripper-smart-skill.behavior.worker.ts
   ├─ assets
   │  ├─ i18n
   │  └─ icons
   ├─ contribution.json
   ├─ index.html
   ├─ main.ts
   └─ styles.scss

2. Add the Behavior

Add the default behavior to the empty gripper-smart-skill.behavior.worker.ts file:

import { registerSmartSkillBehavior, ScriptBuilder, SmartSkillBehaviors } from '@universal-robots/contribution-api';

const behaviors: SmartSkillBehaviors = {
    // factory is required
    factory: () => {
        return { type: 'gripper-smart-skill', name: 'Toggle Gripper' };
    },

    // startExecution is required
    startExecution: (instance) => {
        return new ScriptBuilder();
    },

    // stopExecution is optional
    stopExecution: (instance) => {
        return new ScriptBuilder();
    },
};

registerSmartSkillBehavior(behaviors);

3. Edit the contribution.json file to include the Smart Skill:

{
    "smartSkills": [
        {
            "name": "gripper-smart-skill",
            "iconURI": "assets/icons/gripper.svg",
            "behaviorURI": "gripper-smart-skill.worker.js",
            "translationPath": "assets/i18n/"
        }
    ]
}

4. Add the Smart Skill to the app.module.ts:

registerWorkersWithWebPack() {
    ...
    new Worker(new URL('./components/gripper-smart-skill/gripper-smart-skill.behavior.worker.ts' /* webpackChunkName: "gripper-smart-skill.worker" */, import.meta.url), {
        name: 'gripper-smart-skill',
        type: 'module',
    });
}

5. Add the translations for your new Smart Skill in the en.json:

{
    "smart_skills": {
        "gripper-smart-skill": "Toggle Gripper"
    }
}

Now reinstall your URCap with the new Smart Skill and see it in the move drawer.

Adding Settings to your Smart Skill

If your users are to change settings and/or parameters for your smart skill, you can add a component and a presenter to your smart skill. An example of a smart skill with a presenter can be seen below. Here the user can change parameters such as the force which the robot uses to determine if a contact has been detected or not.

Files and Folders

Add the *.html, *ts and optionally the *.scss styles file.

└─ gripper-smart-skills
   ├─ gripper-smart-skills.behavior.worker.ts
   ├─ gripper-smart-skills.component.html
   ├─ gripper-smart-skills.component.scss
   └─ gripper-smart-skills.component.ts

The Component

1. Add the parameters

In the gripper.behavior.worker.ts add the parameters field to the factory, specifying all parameters and their initial values:

parameters: {
    push_force: 10,
    velocity_move: 0.1,
    acc_move: 1.0,
    max_radius_search: 0.05,
    num_fingers: 3,
},

2. Add the logic to the component

import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { SmartSkillInstance, SmartSkillPresenter, SmartSkillsPresenterAPI } from '@universal-robots/contribution-api';

@Component({
    templateUrl: './gripper.component.html',
    styleUrls: ['./gripper.component.scss'],
    changeDetection: ChangeDetectionStrategy.OnPush,
})
export class GripperComponentSmartSkill implements SmartSkillPresenter {
    @Input()
    instance: SmartSkillInstance;

    @Input()
    presenterAPI: SmartSkillsPresenterAPI;

    ...

    // Example usage of updateInstance
    updateSmartSkillParameter(variable_name: string, value: any): void {
        this.presenterAPI.smartSkillInstanceService.updateInstance({
            ...this.instance,
            parameters: { ...this.instance.parameters, [variable_name]: value },
        });
    }
}

3. Add the presenter to the App

In the app.module.ts add the creation of the web-component:

ngDoBootstrap() {

    ...

    customElements.define(
        'gripper-component-smart-skill',
        createCustomElement(GripperComponentSmartSkill, { injector: this.injector })
    );
}

And add the presenterURI and the corresponding componentTagName fields to the contribution.json so the backend knows to load them:

{
    "smartSkills": [
        {
            "name": "gripper-smart-skill",
            "iconURI": "assets/icons/gripper.svg",
            "behaviorURI": "gripper-smart-skill.worker.js",
            "presenterURI": "main.js",
            "componentTagName": "gripper-component-smart-skill",
            "translationPath": "assets/i18n/"
        }
    ]
}

Reinstall the URCap with the new smart skill presenter and open the Smart Skill application node to see your new settings view.