Universal Robots Integration Guide
Read joint positions, tool pose, I/O and robot modes over RTDE, stream them into pipelines, read the robot's status, and play, pause, stop or load programs.
- Default ports
- RTDE 30004 · Dashboard 29999
- Authentication
- None (the robot offers none)
- Operations
- Read RTDE · Read Status · Program Command
- Triggers
- Monitor RTDE, one event per publish interval
Universal Robots cobots (CB3 and e-Series, and the URSim simulator) publish their live data through RTDE (Real-Time Data Exchange, TCP port 30004) and take program commands through the Dashboard server (TCP port 29999). MaestroHub connects to both as a client; it never opens a port of its own. This guide covers connection setup, the four function types, the safety rules for program commands, and how the matching nodes and trigger slot into the Pipeline Designer.
Overview
The Universal Robots connector provides:
- Read RTDE: one sample of the RTDE output variables you list: joint positions, TCP pose and speed, digital and analog I/O, robot and safety modes, runtime state, speed scaling and more
- Monitor RTDE trigger: streams the same variables and starts a pipeline once per publish interval (100 ms to 1 h), not once per controller cycle
- Read Status: robot mode, safety status, program state, loaded program, whether a program is running, PolyScope version and remote control, from the Dashboard server
- Program Command: play, pause, stop, or load a
.urpprogram, only when the robot is in remote control, sent at most once
RTDE variables
An RTDE output recipe is the list of variables you want, for example actual_q, actual_TCP_pose, robot_mode, safety_status, runtime_state. The names are UR's (see UR's RTDE guide for your PolyScope version); MaestroHub checks only their shape, and the robot answers for which ones exist. A name the robot does not know is refused and named.
The values arrive under values, by name: numbers, booleans, or arrays for vectors (actual_q is 6 joint angles in radians; actual_TCP_pose is x, y, z in metres and rx, ry, rz as a rotation vector). The mode variables also get a readable name under labels:
| Variable | Labels |
|---|---|
robot_mode | NO_CONTROLLER, DISCONNECTED, CONFIRM_SAFETY, BOOTING, POWER_OFF, POWER_ON, IDLE, BACKDRIVE, RUNNING, UPDATING_FIRMWARE |
safety_mode, safety_status | NORMAL, REDUCED, PROTECTIVE_STOP, RECOVERY, SAFEGUARD_STOP, SYSTEM_EMERGENCY_STOP, ROBOT_EMERGENCY_STOP, VIOLATION, FAULT, … |
runtime_state | STOPPING, STOPPED, PLAYING, PAUSING, PAUSED, RESUMING |
controllerTime is the controller's own clock (RTDE timestamp, seconds since the controller started); serverTimestamp is when MaestroHub received the sample.
What happens on connect
MaestroHub opens the Dashboard server connection and checks its greeting, then opens an RTDE connection, agrees RTDE protocol version 2 and reads the controller version. If either server is turned off on the robot (PolyScope 5: Settings → Security → Services), the connection fails with an error naming the port. Each Monitor RTDE trigger then opens its own RTDE connection; a Read RTDE opens a short one for its sample.
Connection Configuration
Creating a Universal Robots Connection
Navigate to Connections → New Connection → Universal Robots and configure the form. The form has four tabs: Connection, Functions, Scaling, and Health; the last three unlock after the connection is saved.
1. Profile Information
| Field | Default | Description |
|---|---|---|
| Profile Name | - | A descriptive name for this connection profile (required). Must be unique across all connections. |
| Description | - | Optional description for this connection |
| Labels | - | Key-value pairs to categorize and organize the connection |
2. Robot
| Field | Default | Meaning |
|---|---|---|
| Host | (required) | The robot controller's host name or IP address |
| RTDE Port | 30004 | The RTDE server's port. 30004 on every controller |
| Dashboard Server Port | 29999 | The Dashboard server's port. 29999 on every controller |
| Connection Timeout | 10s | Time allowed to open the Dashboard and RTDE connections and receive their greetings |
The robot's RTDE and Dashboard servers have no authentication or encryption. Keep the robot on an isolated cell network, and turn off what you do not use in PolyScope's security settings.
Testing the Connection
Click Test Connection to try the settings before saving. Once the connection runs, its health probe asks the Dashboard server for the robot mode and reports the round trip; an unanswered probe drops the session and the connection reconnects.
Function Builder
Creating Universal Robots Functions
After the connection is saved:
- Open the connection and navigate to the Functions tab
- Click New Function to open the function type selection dialog
- Choose Monitor RTDE, Read RTDE, Read Status, or Program Command
- Fill the Basic tab and the Configuration tab
- Use the Test button to run the function against the robot before saving
Monitor RTDE (universalrobots.monitor)
Purpose: Starts a pipeline with an RTDE sample once per publish interval. This function type is a pipeline trigger: see the Universal Robots Trigger node.
| Parameter | Meaning |
|---|---|
| RTDE Variables | Comma-separated output variable names, at most 64 |
| Publish Interval | At most one pipeline event per interval, from 100ms to 1h (default 1s) |
The robot runs RTDE at 125 Hz (CB3) or 500 Hz (e-Series); a pipeline run per sample would swamp everything downstream. MaestroHub asks the robot for twice the publish rate (at most 10 Hz) and starts a pipeline with the first sample at least one interval after the previous one, measured on the robot's clock.
If no sample arrives for 5 seconds, or the link drops, the trigger fires once with quality bad and the reason, then reconnects on its own.
Read RTDE (universalrobots.read)
Purpose: Returns one sample of the listed RTDE variables, for example actual_q, actual_TCP_pose, robot_mode.
{
"values": { "actual_q": [0, -1.5708, 1.5708, -1.5708, -1.5708, 0], "robot_mode": 7 },
"labels": { "robot_mode": "RUNNING" },
"controllerTime": 12345.678,
"quality": "good",
"serverTimestamp": "2026-10-20T10:14:03.221Z"
}
Read Status (universalrobots.status)
Purpose: Asks the Dashboard server seven status questions and returns robotMode, safetyStatus, programState, programName, loadedProgram, programRunning, polyscopeVersion and remoteControl. A question an older controller does not understand comes back as null and is listed in unsupported, never guessed. It sends no command.
Program Command (universalrobots.programCommand)
Purpose: Plays, pauses or stops the loaded program, or loads a program.
| Parameter | Meaning |
|---|---|
| Command | play (start or resume the loaded program), pause, stop, or load |
| Program | load only: the .urp file, e.g. pick_and_place.urp (relative to the robot's programs folder) or /programs/cell1/pick.urp. At most 255 characters; can be a ((parameter)) |
Make sure the cell is safe before a pipeline can play a program. The robot's own safety system stays in charge; MaestroHub adds these rules:
- Remote control only. Before every command MaestroHub asks the robot whether it is in Remote Control. If it says no, the command is refused and nothing is sent. Switch the robot to Remote Control on the teach pendant to allow it. Controllers without a local/remote mode (CB3, older PolyScope) take the command; the result says
remoteControl: "unsupported". - Checked before sending. A command outside the four, a program that is not a
.urpfile, or a program containing a line break or other control character is refused with nothing sent. - Sent at most once. If the robot does not answer, the link drops, or it answers something unexpected, the outcome is unknown: the robot may have acted. MaestroHub then reports
outcome unknownand never sends it again on its own, not by the connector and not by a pipeline's Retry on Fail or ForEach retry. A command the robot refused (Failed to execute: play,File not found: …) is reported as refused and is not retried either. Commands are never buffered for later delivery, and a pipeline started by a late (replayed) value does not run them unless the node allows late input.
Out of scope in this version: RTDE input writes (registers, I/O), sending URScript, the primary, secondary and real-time interfaces (30001-30003), power on or off, brake release, unlocking a protective stop, closing safety pop-ups, and any motion command beyond play, pause, stop and load.
Pipeline Integration
- Universal Robots Read RTDE (
connected.universalrobots.read): executes auniversalrobots.readfunction - Universal Robots Read Status (
connected.universalrobots.status): executes auniversalrobots.statusfunction - Universal Robots Program Command (
connected.universalrobots.programCommand): executes auniversalrobots.programCommandfunction - Universal Robots Trigger (
trigger.universalrobots): starts a pipeline with each published sample of auniversalrobots.monitorfunction
For node-level details, see the Universal Robots Nodes and Universal Robots Trigger pages.
Common Use Cases
Robot Telemetry to a Historian or UNS
A Monitor RTDE trigger with actual_q, actual_TCP_pose, robot_mode, safety_status every second, routed to the Unified Namespace, gives a live picture of every cobot in the plant with readable modes.
Downtime and Safety Events
Watch robot_mode, safety_status and runtime_state and branch on labels with a Condition node: a PROTECTIVE_STOP or a program that left PLAYING raises an alert or a maintenance ticket.
Order-Driven Program Changes
When a new order arrives, check the robot with Read Status (robotMode is RUNNING, remoteControl is true, programState is STOPPED), then load the order's program and play it. Because a command whose outcome is unknown is never re-sent, read the status again before trying again.
Troubleshooting
Error Reference
| What you see | Meaning | Retried? |
|---|---|---|
the robot is in local control, so the command was not sent | The robot is in Local Control | No: switch to Remote Control on the pendant |
the robot refused play: Failed to execute: play | The robot did not run the command (no program loaded, not powered, a safety stop) | No |
the robot refused load: File not found: … | The program does not exist on the robot | No |
outcome unknown: … | The command may have reached the robot and no verdict came back | Never: read the status first |
the robot does not know the RTDE output variable(s) … | A variable name is misspelt or not in this PolyScope version | No |
did not greet like a Universal Robots Dashboard server | Something else answers on the Dashboard port | No: check host and port |
not connected | The connection is down | Yes, after reconnect |
Connection Issues
| Symptom | Possible Cause | Solution |
|---|---|---|
| Connect fails naming port 29999 or 30004 | The Dashboard server or RTDE is turned off, or a firewall blocks it | PolyScope 5: Settings → Security → Services; open both ports between MaestroHub and the robot |
| Every command is refused as local control | The robot is in Local Control | Enable Remote Control in Settings → System → Remote Control, then switch to it in the PolyScope header |
The trigger fires bad with no RTDE data | The robot stopped sending (controller restart, network) | It reconnects on its own; check the network if it repeats |