Skip to main content
Version: 3.0 (next)

Universal Robots Trigger Node

Start a pipeline with an RTDE sample of a Universal Robots cobot once per publish interval, with readable modes and the controller's own time.

Starts on
Each publish interval (100 ms to 1 h)
Function
Monitor RTDE
Output
One event per interval
Dedup
None: every sample starts a run

Overview​

The Universal Robots Trigger Node starts a MaestroHub pipeline with an RTDE sample of the variables a Monitor RTDE function lists (joint positions, TCP pose, I/O, robot and safety modes, runtime state…). Unlike the Read RTDE node, which reads one sample inside an already-running pipeline, the trigger starts a new execution once per publish interval.

The robot streams RTDE at 125 Hz (CB3) or 500 Hz (e-Series). The trigger asks it for twice the publish rate (at most 10 Hz) and starts a pipeline with the first sample at least one publish interval after the previous one, on the robot's own clock, so a 1 s interval is one run per second however fast the robot runs.

Reconnection Handling​

  • If no sample arrives for 5 seconds, or the RTDE link drops, the trigger fires once with _metadata.quality bad and the reason under _metadata.error. Its result is the last sample delivered (an empty object if none had arrived yet).
  • The stream then reconnects on its own (after 1 s, backing off to 30 s) while the connection is up, and the next sample is good again.
  • When the whole connection reconnects, every trigger's stream is started again; nothing needs re-enabling.

Configuration Options​

FieldMeaning
ConnectionA Universal Robots connection
FunctionA Monitor RTDE function on it
EnabledOff keeps the node but never subscribes

The function sets RTDE Variables (comma-separated, at most 64) and Publish Interval (100ms to 1h, default 1s). See Monitor RTDE.

Output Data Structure​

Output Format​

{
"_metadata": {
"type": "universalrobots_trigger",
"protocol": "universalrobots",
"connectionId": "bf29be94-fc0a-4dc4-8e5c-092f1b74eb4b",
"functionId": "aef374c3-aa2b-454e-aabc-5657faac5950",
"controllerTime": "12345.678",
"serverTimestamp": "2026-10-20T10:14:03.221Z",
"quality": "good",
"timestamp": "2026-10-20T10:14:03.221123456Z"
},
"result": {
"values": { "actual_q": [0, -1.5708, 1.5708, -1.5708, -1.5708, 0], "robot_mode": 7, "runtime_state": 2 },
"labels": { "robot_mode": "RUNNING", "runtime_state": "PLAYING" },
"controllerTime": 12345.678,
"quality": "good",
"serverTimestamp": "2026-10-20T10:14:03.221Z"
}
}

result Fields​

FieldTypeDescription
valuesobjectOne entry per variable, by name: numbers, booleans, or arrays for vectors.
labelsobjectReadable names for robot_mode, safety_mode, safety_status and runtime_state when they are in the recipe; UNKNOWN for a code this release does not know.
controllerTimenumberThe controller's clock, seconds since it started. Not wall-clock time.
qualitystringgood for a sample the robot sent.
serverTimestampstringWhen MaestroHub received the sample, UTC.

_metadata Fields​

FieldTypeDescription
typestringAlways "universalrobots_trigger".
protocolstringAlways "universalrobots".
connectionIdstringThe connection profile ID.
functionIdstringThe Monitor RTDE function ID.
controllerTimestringThe controller's clock, as a string.
serverTimestampstringRFC 3339, UTC; when MaestroHub received the sample.
qualitystringgood, or bad on the once-per-outage failure event.
quality_reasonstringOnly on a failure event: comm_error.
errorstringOnly on a failure event: why the stream was lost.
timestampstringRFC 3339 (nanoseconds); when the trigger event was created, UTC.

Referencing in Downstream Nodes​

  • $trigger.result.values.actual_q: the joint positions
  • $trigger.result.labels.robot_mode: e.g. RUNNING
  • $trigger.result.controllerTime: the robot's clock
  • $trigger.result.quality and $trigger._metadata.quality: bad on the failure event
  • $trigger.result.serverTimestamp: when the sample arrived
  • $trigger._metadata.connectionId, $trigger._metadata.functionId: the connection and function used

Best Practices​

  • Choose the longest publish interval that answers your question: one event per second per robot is plenty for dashboards and downtime tracking.
  • List only the variables you use; each is decoded and carried in every event.
  • Branch on labels rather than numeric codes, so a pipeline reads labels.safety_status == "PROTECTIVE_STOP".