UnderAutomation
Eine Frage?

[email protected]

Kontakt
UnderAutomation
⌘Q
Diese Seite ist nur auf Englisch verfügbar.

Get started with Matlab

Load the .NET DLL of the ABB SDK in Matlab with NET.addAssembly, then read positions, I/O signals, RAPID variables and tasks of an IRC5 or OmniCore controller from a Matlab script.

  • Requirements
  • Load the SDK
  • First program
  • From .NET to Matlab
  • Examples
  • Discover the controllers
  • Read the position
  • Read and write I/O signals
  • Read and write RAPID variables
  • RAPID tasks
  • Known limits
  • What to read next

This page shows how to use the ABB SDK from Matlab, to read and control an IRC5 or an OmniCore controller from a Matlab script. Matlab loads the .NET DLL of the SDK with its .NET interface: nothing else is installed, on the PC or on the controller.

Requirements

ItemSupported
WindowsMatlab with the .NET Framework 4.6.2 or later (the default on Windows 10 and 11). Load the net48 DLL
Linux and macOSMatlab R2024b or later with the .NET runtime, selected by dotnetenv("core"). Not tested by UnderAutomation yet
ControllersIRC5 with RobotWare 6 and OmniCore with RobotWare 7, real or virtual in RobotStudio

Matlab documents its .NET interface in Call .NET from MATLAB.

Load the SDK

  1. Download UnderAutomation.ABB.zip from the latest release of ABB.NET.
  2. On Windows, unblock the zip before you extract it: right click, Properties, check Unblock.
  3. Copy its net48 folder next to your script.
  4. Load the DLL with NET.addAssembly, then import the namespaces you use.
% The net48 folder of UnderAutomation.ABB.zip, copied next to this script
dll = fullfile(pwd, 'net48', 'UnderAutomation.ABB.dll');
if ~NET.isNETSupported
error('No supported .NET Framework found on this computer');
end
% Load the SDK once per Matlab session
NET.addAssembly(dll);
% Import the namespaces you use
import UnderAutomation.ABB.*
import UnderAutomation.ABB.Rws.*
import UnderAutomation.ABB.Rws.Data.*

NET.addAssembly needs an absolute path: fullfile(pwd, ...) builds one that works on every operating system. Matlab cannot unload a .NET assembly: restart Matlab to load a new version of the DLL.

On Linux and macOS, Matlab R2024b and later can use the .NET runtime instead of the .NET Framework. Set the environment variable DOTNET_ROOT to the folder of the .NET runtime, call dotnetenv("core") before NET.addAssembly, and load the DLL of the net8.0 folder. See dotnetenv in the Matlab documentation.

First program

NET.addAssembly(fullfile(pwd, 'net48', 'UnderAutomation.ABB.dll'));
import UnderAutomation.ABB.*
% Connect to an OmniCore controller with the default RWS parameters
robot = AbbController();
robot.Connect('192.168.0.1');
% Every RWS service is reachable from robot.Rws
identity = robot.Rws.Controller.GetIdentity();
disp(char(identity.Name));
robot.Disconnect();

The default parameters target an OmniCore controller. For an IRC5 with RobotWare 6, or for another user account, use ConnectionParameters:

NET.addAssembly(fullfile(pwd, 'net48', 'UnderAutomation.ABB.dll'));
import UnderAutomation.ABB.*
import UnderAutomation.ABB.Rws.*
parameters = ConnectionParameters('192.168.0.1');
% Ping the controller first, so an unreachable robot fails immediately
parameters.PingBeforeConnect = true;
parameters.Rws.Enable = true;
parameters.Rws.Username = 'Default User';
parameters.Rws.Password = 'robotics';
parameters.Rws.UseHttps = false;
parameters.Rws.Port = 0; % 0 means 80 for HTTP and 443 for HTTPS
parameters.Rws.Timeout = 10000;
% IRC5 with RobotWare 6: RwsVersion.Irc5_V1_0
parameters.Rws.Version = RwsVersion.OmniCore_V2_0;
robot = AbbController();
robot.Connect(parameters);
robot.Disconnect();

When the controller answers on HTTPS with a certificate it signed itself, the SDK accepts it and enables TLS 1.2. Nothing has to be set in Matlab. See Connect to your robot.

The SDK runs for 30 days without a key. After that, register your license once per Matlab session:

NET.addAssembly(fullfile(pwd, 'net48', 'UnderAutomation.ABB.dll'));
import UnderAutomation.ABB.*
% Register the license once, before the first connection
AbbController.RegisterLicense('YourCompanyName', 'YOUR_LICENSE_KEY');
info = AbbController.LicenseInfo;
% A readable description of the current state
disp(char(info.ToString()));
% Check the license once at startup
if ~info.IsLicensed
error(char(info.ToString()));
end

From .NET to Matlab

The names of the classes, methods and properties are the .NET names of the other pages. The C# samples of the documentation translate line by line, with these rules:

.NETMatlab
new AbbController()AbbController(), after import UnderAutomation.ABB.*
"192.168.0.1"'192.168.0.1', a char vector
GetJointTarget("ROB_1", alwaysRead: true)GetJointTarget('ROB_1', true): no named arguments
An optional argument, like toolPass every argument. [] passes null
A float argument, like a signal valuesingle(1)
An int argument, like a timeoutint32(2000)
A nullable value (float?, bool?)An object with HasValue and Value, or GetValueOrDefault()
tasks[0]tasks(1): Matlab indexes .NET arrays from 1
tasks.Lengthtasks.Length
An enumeration value, like task.ExecutionStatechar(task.ExecutionState) gives its name
MastershipDomain.RapidMastershipDomain.Rapid, after import UnderAutomation.ABB.Rws.Data.*
try { } finally { }try ... catch, then the cleanup in both branches

Examples

Discover the controllers

NET.addAssembly(fullfile(pwd, 'net48', 'UnderAutomation.ABB.dll'));
import UnderAutomation.ABB.*
% Looks for two seconds, no license and no connection needed
found = AbbController.Discover(int32(2000));
% .NET arrays are indexed from 1 in Matlab
for i = 1:found.Length
controller = found(i);
fprintf('%s at %s:%d, RobotWare %s\n', char(controller.SystemName), ...
char(controller.Address), controller.Port, char(controller.RobotWareVersion));
end

Read the position

NET.addAssembly(fullfile(pwd, 'net48', 'UnderAutomation.ABB.dll'));
import UnderAutomation.ABB.*
import UnderAutomation.ABB.Rws.Data.*
robot = AbbController();
robot.Connect('192.168.0.1');
% Tool position in millimeters, in the base frame, with the active tool and work object.
% Pass every argument: [] passes null for the tool and the work object.
target = robot.Rws.MotionSystem.GetRobTarget('ROB_1', CoordinateSystem.Base, [], []);
fprintf('X=%.1f Y=%.1f Z=%.1f\n', target.X, target.Y, target.Z);
% Orientation as a quaternion
q = target.Orientation;
fprintf('q = [%.4f, %.4f, %.4f, %.4f]\n', q.Q1, q.Q2, q.Q3, q.Q4);
% Joint values of the robot axes, in degrees
joints = robot.Rws.MotionSystem.GetJointTarget('ROB_1', false);
robotAxes = joints.RobotAxes;
j = [robotAxes.Axis1, robotAxes.Axis2, robotAxes.Axis3, robotAxes.Axis4, robotAxes.Axis5, robotAxes.Axis6];
robot.Disconnect();

Read and write I/O signals

NET.addAssembly(fullfile(pwd, 'net48', 'UnderAutomation.ABB.dll'));
import UnderAutomation.ABB.*
robot = AbbController();
robot.Connect('192.168.0.1');
% A signal is identified by its network, its device and its name
signal = robot.Rws.Io.GetSignal('Local', 'Board10', 'DO_Gripper');
% LogicalValue is a .NET Nullable: HasValue is false when the controller gave no value
if signal.LogicalValue.HasValue
fprintf('%s = %g (%s)\n', char(signal.Path), signal.LogicalValue.Value, char(signal.Type));
end
% Every signal of the controller, in one call
signals = robot.Rws.Io.GetSignals();
for i = 1:signals.Length
fprintf('%s = %g\n', char(signals(i).Path), signals(i).LogicalValue.GetValueOrDefault());
end
robot.Disconnect();
NET.addAssembly(fullfile(pwd, 'net48', 'UnderAutomation.ABB.dll'));
import UnderAutomation.ABB.*
robot = AbbController();
robot.Connect('192.168.0.1');
% The value is a .NET float: convert it with single().
% The last argument writes the change in the event log of the controller.
% A digital signal takes 0 or 1
robot.Rws.Io.SetSignalValue('Local', 'Board10', 'DO_Gripper', single(1), false);
% An analog or a group signal takes any value inside its range
robot.Rws.Io.SetSignalValue('Local', 'Board10', 'AO_Speed', single(12.5), false);
robot.Disconnect();

Read and write RAPID variables

NET.addAssembly(fullfile(pwd, 'net48', 'UnderAutomation.ABB.dll'));
import UnderAutomation.ABB.*
robot = AbbController();
robot.Connect('192.168.0.1');
% A value always comes back as the text RAPID writes it with. Reading needs no mastership.
value = robot.Rws.Rapid.GetSymbolValue('RAPID/T_ROB1/user/reg1');
% num and dnum: RAPID uses a dot as decimal separator, like Matlab
number = str2double(char(value.Value));
% bool: the controller writes TRUE or FALSE
flag = strcmpi(strtrim(char(robot.Rws.Rapid.GetSymbolValue('RAPID/T_ROB1/MainModule/myFlag').Value)), 'TRUE');
% string: the value carries the RAPID quotes, remove them
message = strip(char(robot.Rws.Rapid.GetSymbolValue('RAPID/T_ROB1/MainModule/myText').Value), '"');
robot.Disconnect();

Writing needs the RAPID mastership. See Mastership.

NET.addAssembly(fullfile(pwd, 'net48', 'UnderAutomation.ABB.dll'));
import UnderAutomation.ABB.*
import UnderAutomation.ABB.Rws.Data.*
robot = AbbController();
robot.Connect('192.168.0.1');
% Writing needs the RAPID mastership. Take it, write, give it back.
robot.Rws.Mastership.Request(MastershipDomain.Rapid);
try
% num: sprintf always writes a dot as decimal separator
robot.Rws.Rapid.SetSymbolValue('RAPID/T_ROB1/user/reg1', sprintf('%g', 1.5));
% bool: TRUE or FALSE, in capitals
robot.Rws.Rapid.SetSymbolValue('RAPID/T_ROB1/MainModule/myFlag', 'TRUE');
% string: the RAPID quotes are part of the value
robot.Rws.Rapid.SetSymbolValue('RAPID/T_ROB1/MainModule/myText', '"hello"');
catch ex
robot.Rws.Mastership.Release(MastershipDomain.Rapid);
rethrow(ex);
end
robot.Rws.Mastership.Release(MastershipDomain.Rapid);
robot.Disconnect();

RAPID tasks

NET.addAssembly(fullfile(pwd, 'net48', 'UnderAutomation.ABB.dll'));
import UnderAutomation.ABB.*
robot = AbbController();
robot.Connect('192.168.0.1');
tasks = robot.Rws.Rapid.GetTasks();
for i = 1:tasks.Length
task = tasks(i);
% char() gives the name of an enumeration value: Started, Stopped, Ready...
fprintf('%s: %s, %s\n', char(task.Name), char(task.Type), char(task.ExecutionState));
end
robot.Disconnect();

Known limits

  • Use the synchronous methods. The asynchronous methods (...Async) return a .NET Task, which Matlab cannot await.
  • Matlab has no named arguments: pass all the arguments of a .NET method, in order.
  • An exception of the SDK is a NET.NetException in Matlab. Its ExceptionObject property holds the .NET exception, with its Message. For an RwsException, ExceptionObject.StatusCode is the HTTP status of the answer.
  • Matlab keeps the DLL loaded until it closes.

See also the Matlab pages on the limits of .NET arrays, .NET methods and .NET enumerations.

What to read next

  • Connect to your robot: connection parameters, IRC5 and OmniCore, errors.
  • Test with a RobotStudio virtual controller: work without a real robot.
  • Robot Web Services overview: the services of the SDK, one page per topic.
  • Licensing: the 30 day trial and the license key.

Integrieren Sie Roboter von Universal Robots, Fanuc, Yaskawa, ABB oder Staubli ganz einfach in Ihre .NET-, Python-, LabVIEW- oder Matlab-Anwendungen

UnderAutomation
KontaktLegal

© All rights reserved.