Universal Robots real-time data exchange (RTDE) using C##
A colleague and me wanted to find a C# library for controlling a Universal Robots UR3 robot arm with an OnRobot RG2 gripper for using in an industrial programming-related course.
At the end we could not find an open source-based solution and went for licensing the non-free library by UnderAutomation. In the following I wrote down my results.
I have used the following libraries:
sdurobotics/ur_rtde: A high-quality open-source C++ library from SDU with Python bindings. It can automatically load the control script for the robot and even restart it after a safety lock.
RyanPaulMcKenna/onRobot: A low-quality Python library, but it is the only one that I could find that can interface with the UR robot. It can get the gripper width and apply width along with force.
Using the two above I could successfully move the gripper to a pose in base coordinates and open & close the gripper.
Other libraries I stumbled upon but did not use:
https://sourceforge.net/p/firsttestfchaxel/code/HEAD/tree/trunk/Ur_Rtde: An undocumented C# library, which lacks functions like automatic loading of control script and inverse kinematics for controlling the gripper in base coordinates.
takuya-ki/onrobot-rg: Python library for some OnRobot grippers. Can only interface the control box of the gripper directly.
RoboDK: Commercial simulator and programmer with support for most industrial robot arms. Features a C# API. This solution is non-free and probably abstract too much for a C# programming course.
UniversalRobots: A high-quality commercial C# library for RTDE that must be licensed. They provide an academic license with ~40% off at 594 EUR. According to UnderAutomation it is a perpetual license independent of how many students or robots.
Failure at wrapping C++ code for using in C#:#
I tried to wrap ur_rtde
for using in the .NET environment, but could not manage it in an acceptable time frame. In the following you find my notes.
In the following I assume that you downloaded and compiled ur_rtde
.
Using SWIG#
ur_rtde
is based on C++ and the easiest solution to create a C# wrapper is to use SWIG, which in ideal case does not require any manual code. Unfortunately, ur_rtde
uses C++ keywords that SWIG could not parse, e.g., RTDE_EXPORT
. Removing these attributes solves the problem.
Another problem is typing mismatches between C++ and C#, e.g., std:vector<double>
does not have a direct correspondence in C#, so the user must provide a manual mapping.
Using CppSharp#
I tried to create a wrapper using:
dotnet new console -n test
cd test
dotnet add package cppsharp
Then used the following program to parse ur_rtde
headers following the tutorial:
Program.cs
:
using CppSharp;
using CppSharp.AST;
using CppSharp.Generators;
public class URRTDELibrary : ILibrary
{
public void Setup(Driver driver)
{
// Define the options for the driver
var options = driver.Options;
options.GeneratorKind = GeneratorKind.CSharp;
var module = options.AddModule("ur_rtde");
module.IncludeDirs.Add("include");
module.Headers.Add("ur_rtde/rtde_control_interface.h");
module.LibraryDirs.Add("lib");
module.Libraries.Add("librtde.so"); // Or librtde.dll for Windows
}
public void SetupPasses(Driver driver) { }
public void Preprocess(Driver driver, ASTContext ctx) { }
public void Postprocess(Driver driver, ASTContext ctx) { }
}
class Program
{
static void Main(string[] args)
{
ConsoleDriver.Run(new URRTDELibrary());
}
}
Then run it:
$ dotnet build && dotnet run
Parsing libraries...
Parsed 'librtde.so'
Parsing code...
Parsed 'ur_rtde/rtde_control_interface.h'
Processing code...
Generating code...
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
at CppSharp.AST.ClassExtensions.HasDependentValueFieldInLayout(Class class, IEnumerable`1 specializations)
I have the hunch this error is due to unsupported datatypes like std:vector<double>
. I had a similar error in SWIG.
Manual wrapping methods#
There are two other wrapping methods:
Both methods require manually creating a wrapper between the native C++ code and the managed C# code. ur_rtde
comprises dozens of functions, so this could take days. I believe SWIG and CppSharp use one of these methods under the hood.