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 Universal Robots SDK in Matlab with NET.addAssembly, and read and control a UR cobot from a Matlab script.

  • Requirements
  • Load the SDK
  • First program
  • From .NET to Matlab
  • Examples
  • Data exchange with RTDE
  • URScript and files
  • Socket server
  • Kinematics and files, without a robot
  • Known limits
  • What to read next

This page shows how to use the Universal Robots SDK from Matlab, to read and control a UR cobot 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 robot.

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
RobotsCB-Series, e-Series, UR8 Long, UR15, UR18, UR20, UR30, with PolyScope or PolyScope X, and URSim

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

Load the SDK

  1. Download UnderAutomation.UniversalRobots.zip from the latest release of UniversalRobots.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.UniversalRobots.zip, copied next to this script
dll = fullfile(pwd, 'net48', 'UnderAutomation.UniversalRobots.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.UniversalRobots.*
import UnderAutomation.UniversalRobots.Common.*
import UnderAutomation.UniversalRobots.Rtde.*

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.UniversalRobots.dll'));
import UnderAutomation.UniversalRobots.*
robot = UR();
% Primary Interface and Dashboard Server
robot.Connect('192.168.0.1');
% Power on the arm and release the brakes
robot.Dashboard.PowerOn();
robot.Dashboard.ReleaseBrake();
% Load a program and start it
robot.Dashboard.LoadProgram('pick_and_place.urp');
robot.Dashboard.Play();
% Name and state of the program
state = robot.Dashboard.GetProgramState();
disp(char(state.Value.Name));
disp(char(state.Value.State.ToString()));
% Show a message on the teach pendant
robot.Dashboard.ShowPopup('Started from Matlab');
robot.Disconnect();

The connection parameters select the interfaces, like in C#:

NET.addAssembly(fullfile(pwd, 'net48', 'UnderAutomation.UniversalRobots.dll'));
import UnderAutomation.UniversalRobots.*
import UnderAutomation.UniversalRobots.Rtde.*
robot = UR();
parameters = ConnectParameters('192.168.0.1');
% Enabled by default
parameters.PrimaryInterface.Enable = true;
parameters.Dashboard.Enable = true;
% RTDE: select the data to exchange and the frequency
parameters.Rtde.Enable = true;
parameters.Rtde.Frequency = 125;
parameters.Rtde.OutputSetup.Add(RtdeOutputData.ActualTcpPose, int32(0));
parameters.Rtde.OutputSetup.Add(RtdeOutputData.ActualQ, int32(0));
parameters.Rtde.InputSetup.Add(RtdeInputData.InputIntRegisters, int32(24));
% SSH and SFTP, with the Linux user of the controller
parameters.Ssh.EnableSftp = true;
parameters.Ssh.Username = 'ur';
parameters.Ssh.Password = 'easybot';
robot.Connect(parameters);
robot.Disconnect();

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

NET.addAssembly(fullfile(pwd, 'net48', 'UnderAutomation.UniversalRobots.dll'));
import UnderAutomation.UniversalRobots.*
% Register the license once, before the first connection
UR.RegisterLicense('YourCompanyName', 'YOUR_LICENSE_KEY');
info = UR.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 UR()UR(), after import UnderAutomation.UniversalRobots.*
"192.168.0.1"'192.168.0.1', a char vector
OutputSetup.Add(RtdeOutputData.ActualQ)OutputSetup.Add(RtdeOutputData.ActualQ, int32(0))
An optional argumentPass every argument, with its .NET type: int32(24), uint8(1)
double[] returnedA .NET array: double(values) converts it to a Matlab vector
items[0]items(1): Matlab indexes .NET arrays from 1
robot.Rtde.OutputDataReceived += Handler;addlistener(robot.Rtde, 'OutputDataReceived', @handler)
A string returnedchar(value) converts it to a char vector

Examples

Data exchange with RTDE

NET.addAssembly(fullfile(pwd, 'net48', 'UnderAutomation.UniversalRobots.dll'));
import UnderAutomation.UniversalRobots.*
import UnderAutomation.UniversalRobots.Rtde.*
robot = UR();
parameters = ConnectParameters('192.168.0.1');
% RTDE at 125 Hz (up to 500 Hz)
parameters.Rtde.Enable = true;
parameters.Rtde.Frequency = 125;
% Data that the robot sends
parameters.Rtde.OutputSetup.Add(RtdeOutputData.ActualTcpPose, int32(0));
parameters.Rtde.OutputSetup.Add(RtdeOutputData.ActualTcpForce, int32(0));
% Data that Matlab writes
parameters.Rtde.InputSetup.Add(RtdeInputData.StandardAnalogOutputMask, int32(0));
parameters.Rtde.InputSetup.Add(RtdeInputData.StandardAnalogOutput0, int32(0));
parameters.Rtde.InputSetup.Add(RtdeInputData.InputBitRegisters, int32(64));
robot.Connect(parameters);
% Read the last values received, 10 times
for i = 1:10
pose = robot.Rtde.OutputDataValues.ActualTcpPose;
fprintf('X=%.4f Y=%.4f Z=%.4f\n', pose.X, pose.Y, pose.Z);
pause(0.1);
end
% Write analog output 0 and bit register 64
inputs = RtdeInputValues();
inputs.StandardAnalogOutputMask = uint8(1);
inputs.StandardAnalogOutput0 = 0.2;
inputs.InputBitRegisters.X64 = true;
robot.Rtde.WriteInputs(inputs);
% Or an event, raised at each package. The sender is the RTDE client
listener = addlistener(robot.Rtde, 'OutputDataReceived', @onData);
pause(1);
delete(listener);
robot.Disconnect();
function onData(sender, e)
force = e.OutputDataValues.ActualTcpForce;
fprintf('Fz=%.2f N\n', force.Z);
end

URScript and files

NET.addAssembly(fullfile(pwd, 'net48', 'UnderAutomation.UniversalRobots.dll'));
import UnderAutomation.UniversalRobots.*
robot = UR();
parameters = ConnectParameters('192.168.0.1');
% Primary Interface: send URScript
parameters.PrimaryInterface.Enable = true;
% SFTP: files of the robot
parameters.Ssh.EnableSftp = true;
robot.Connect(parameters);
% Run a URScript line
robot.PrimaryInterface.Script.Send('movej([-1.5, -1.5, -2, -0.5, 1.8, 0], a=1.4, v=1.05)');
% List the programs of the robot. .NET arrays start at 1 in Matlab
items = robot.Sftp.ListDirectory('/programs/');
for i = 1:items.Length
disp(char(items(i).Name));
end
% Download a program, then send it back
local = fullfile(tempdir, 'prg.urp');
robot.Sftp.DownloadFile('/programs/prg.urp', local);
robot.Sftp.UploadFile(local, '/programs/prg_copy.urp');
% Rename, check, delete
robot.Sftp.RenameFile('/programs/prg_copy.urp', '/programs/prg2.urp');
exists = robot.Sftp.Exists('/programs/prg2.urp');
robot.Sftp.DeleteFile('/programs/prg2.urp');
robot.Disconnect();

Socket server

NET.addAssembly(fullfile(pwd, 'net48', 'UnderAutomation.UniversalRobots.dll'));
import UnderAutomation.UniversalRobots.*
robot = UR();
parameters = ConnectParameters('192.168.0.1');
% Socket server on port 50001
parameters.SocketCommunication.Enable = true;
parameters.SocketCommunication.Port = 50001;
robot.Connect(parameters);
% The robot connects with the URScript function socket_open()
addlistener(robot.SocketCommunication, 'SocketClientConnection', @onConnection);
% The robot sends a message with socket_send_string()
addlistener(robot.SocketCommunication, 'SocketRequest', @onRequest);
% Send a message to every connected robot
robot.SocketCommunication.SocketWrite('123456');
function onConnection(sender, e)
e.Client.SocketWrite('Hello robot');
end
function onRequest(sender, e)
disp(char(e.Message));
end

Kinematics and files, without a robot

NET.addAssembly(fullfile(pwd, 'net48', 'UnderAutomation.UniversalRobots.dll'));
import UnderAutomation.UniversalRobots.Common.*
import UnderAutomation.UniversalRobots.Kinematics.*
import UnderAutomation.UniversalRobots.Files.*
% X, Y, Z in m, rotation vector RX, RY, RZ in rad
pose = Pose(0.1, 0.2, -0.1, 0, 0.05, 0.1);
% Convert the rotation to roll, pitch, yaw, and back
rpy = pose.FromRotationVectorToRPY();
rotationVector = rpy.FromRPYToRotationVector();
% Nominal DH parameters of a UR3e
dh = KinematicsUtils.GetDhParametersFromModel(RobotModelsExtended.UR3e);
% Forward kinematics, joint positions in rad
fk = KinematicsUtils.ForwardKinematics([0, -1.57, 1.57, 0, 0, 0], dh);
flange = Pose.From4x4MatrixToRotationVector(fk.ToolTransform);
% Inverse kinematics: up to 8 solutions
solutions = KinematicsUtils.InverseKinematics(pose.FromRotationVectorTo4x4Matrix(), dh);
% Open a program file, as XML
program = URProgram.Load(fullfile(tempdir, 'prg.urp'));
xml = program.XML;

Known limits

  • Matlab has no named arguments: pass all the arguments of a .NET method, in order.
  • A function given to addlistener receives the sender and the event arguments. It does not see the variables of the script: use the sender, as in the RTDE example above.
  • An exception of the SDK is a NET.NetException in Matlab. Its ExceptionObject property holds the .NET exception, with its Message.
  • Matlab keeps the DLL loaded until it closes.

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

What to read next

  • Connect to the robot: the settings of the robot for each interface.
  • RTDE: exchange data up to 500 Hz.
  • 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.