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.