Universal Robots Communication SDK for Python
๐ค Effortlessly Communicate with Universal Robots Cobots
The Universal Robots SDK for Python enables seamless integration with UR cobots (CB-Series and e-Series) for automation, data exchange, and remote control through all native communication protocols.
Whether you're building a custom MES/SCADA integration, a monitoring dashboard, or a test harness, this SDK provides a single Pythonic API for every UR interface.
It supports communication with real robots and URSim simulators.
๐ More Information: https://underautomation.com/universal-robots
๐ Also available in ๐ฆ .NET & ๐จ LabVIEW & ๐ง Unity
โญ Star this repo if it's useful to you!
๐๏ธ Watch for updates
๐ TL;DR
- โก RTDE โ stream real-time robot data at up to 500 Hz (TCP pose, joint angles, forces, I/O, registers)
- ๐ Dashboard Server โ load, play, stop programs; power on/off; robot mode (Polyscope Legacy)
- ๐ REST API โ full HTTP control of robot and program state (PolyscopeX only)
- ๐ Primary Interface โ subscribe to telemetry packets; send URScript commands
- ๐ SFTP โ list, download and upload programs and files over SSH
- ๐ฆพ Kinematics โ offline forward & inverse kinematics for all UR models (no connection needed)
- ๐ Socket Communication โ bidirectional messaging between Python and URScript programs
- ๐ License management โ trial, registration, and status
All protocols use standard UR communication : no custom robot options required.
๐ Installation & Getting Started
Prerequisites
- Python 3.7 or higher
- A UR robot or URSim simulator
Step 1 - Create a Virtual Environment
mkdir my-ur-project
cd my-ur-project
python -m venv venv
# On Windows:
venv\Scripts\activate
# On macOS/Linux:
source venv/bin/activate
Step 2 - Install the SDK
pip install UnderAutomation.UniversalRobots
All dependencies (including pythonnet) are installed automatically.
On Linux, also install .NET runtime and set the PYTHONNET_RUNTIME variable:
sudo apt-get install -y dotnet-runtime-8.0
export PYTHONNET_RUNTIME=coreclr
Alternative: install from source
git clone https://github.com/underautomation/UniversalRobots.py.git cd UniversalRobots.py pip install -e .
Step 3 - Connect to Your Robot
from underautomation.universal_robots.ur import UR
from underautomation.universal_robots.connect_parameters import ConnectParameters
from underautomation.universal_robots.rtde.rtde_output_data import RtdeOutputData
from underautomation.universal_robots.rtde.rtde_input_data import RtdeInputData
from underautomation.universal_robots.rtde.rtde_input_values import RtdeInputValues
robot = UR()
# Configure protocols
params = ConnectParameters("192.168.0.1")
# Dashboard Server (load/play/stop programs, robot state)
params.dashboard.enable = True
# Primary Interface (telemetry packets, URScript)
params.primary_interface.enable = True
# RTDE (real-time data at up to 500 Hz)
params.rtde.enable = True
params.rtde.frequency = 10
params.rtde.output_setup.add(RtdeOutputData.ActualTcpPose)
params.rtde.output_setup.add(RtdeOutputData.ActualQ)
params.rtde.input_setup.add(RtdeInputData.InputIntRegisters, 24)
# SFTP file transfer over SSH
params.ssh.enable = True
params.ssh.enable_sftp = True
params.ssh.username = "ur"
params.ssh.password = "easybot"
# Connect (if you get a license exception, request a free trial at https://underautomation.com/license)
robot.connect(params)
# Read live TCP pose via RTDE
@robot.rtde.output_data_received
def on_rtde(sender, event):
pose = robot.rtde.output_data_values.actual_tcp_pose
print(f"TCP: x={pose[0]:.3f} y={pose[1]:.3f} z={pose[2]:.3f}")
# Send a URScript command
robot.primary_interface.script.send('popup("Hello from Python!", blocking=False)')
# Dashboard: load and start a program
robot.dashboard.load_program("my_program.urp")
robot.dashboard.play()
# SFTP: list programs on the controller
programs = robot.sftp.enumerate_programs()
for p in programs:
print(p)
# Don't forget to disconnect
robot.disconnect()
๐ Licensing
The SDK works out of the box for 30 days (trial period) : no registration needed.
After the trial, you can:
- Buy a license at underautomation.com/order
- Get a new trial period immediately by email at underautomation.com/license
To register a license in code:
from underautomation.universal_robots.ur import UR
license_info = UR.register_license("your-licensee", "your-license-key")
print(license_info)
๐ Examples
The repository includes a complete set of ready-to-run examples in the examples/ folder, organized by communication protocol.
How the Examples Work
| File | Role |
|---|---|
examples/launcher.py |
Interactive menu : browse and run any example from a single launcher |
examples/__init__.py |
Shared helpers : path setup, robot IP persistence, SSH credentials, license management |
examples/robot_config.json |
Saved settings (git-ignored) : remembers your robot IP, credentials, and license key |
Run an example directly:
# First time: will ask for robot IP and save it
python examples/dashboard/dashboard_get_robot_state.py
Or browse all examples with the interactive launcher:
python examples/launcher.py
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
โ Universal Robots Python SDK - Interactive Example Launcher โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ SELECT A CATEGORY โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฃ
โ โ
โ ๐ 1. DASHBOARD (4 examples) โ
โ Dashboard Server (Polyscope Legacy) - load/play/stop programs, ... โ
โ โ
โ ๐ฆพ 2. KINEMATICS (1 example) โ
โ Kinematics - offline forward & inverse kinematics, no connection neededโ
โ โ
โ ๐ 3. LICENSE (1 example) โ
โ License management - activation & status โ
โ โ
โ ๐ 4. PRIMARY_INTERFACE (3 examples) โ
โ Primary Interface - robot telemetry packets, send URScript โ
โ โ
โ ๐ 5. REST (3 examples) โ
โ REST API (PolyscopeX) - robot & program control via HTTP โ
โ โ
โ โก 6. RTDE (2 examples) โ
โ RTDE - real-time data streaming up to 500 Hz, I/O & registers โ
โ โ
โ ๐ 7. SFTP (3 examples) โ
โ SFTP - file transfer, list/download/upload programs โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฃ
โ 0. Exit โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Complete Example List
๐ Dashboard - Polyscope Legacy (port 29999)
| # | Example | Description |
|---|---|---|
| 1 | dashboard_get_robot_state.py | Read robot mode, loaded program, program state, and Polyscope version |
| 2 | dashboard_load_play_program.py | Load a .urp program and start it remotely |
| 3 | dashboard_power_on_release_brakes.py | Power on the robot arm and release brakes from Python |
| 4 | dashboard_popup_message.py | Show a popup on the teach pendant and close it programmatically |
๐ REST API - PolyscopeX (port 80)
| # | Example | Description |
|---|---|---|
| 1 | rest_get_robot_state.py | Read current robot state and program state via HTTP |
| 2 | rest_load_play_program.py | Load and start a program via the REST API |
| 3 | rest_power_on_brake_release.py | Power on the robot and release brakes via the REST API |
โก RTDE - Real-Time Data Exchange (port 30004)
| # | Example | Description |
|---|---|---|
| 1 | rtde_read_tcp_pose.py | Stream TCP pose (x,y,z,rx,ry,rz) and joint angles in real time |
| 2 | rtde_read_digital_io.py | Monitor digital input and output states with change detection |
| 3 | rtde_read_write_registers.py | Read output integer registers and write input integer registers |
๐ SFTP - File Transfer over SSH (port 22)
| # | Example | Description |
|---|---|---|
| 1 | sftp_list_programs.py | List all .urp programs and browse the robot file system |
| 2 | sftp_download_program.py | Download a .urp program file from the controller |
| 3 | sftp_upload_program.py | Upload a local .urp program file to the controller |
๐ Primary Interface (port 30001)
| # | Example | Description |
|---|---|---|
| 1 | primary_interface_read_telemetry.py | Subscribe to robot mode, joint data, and cartesian info events |
| 2 | primary_interface_send_urscript.py | Send URScript commands directly to the robot controller |
| 3 | primary_interface_global_variables.py | Read global variables declared in the loaded Polyscope program |
๐ฆพ Kinematics - Offline FK & IK (no connection needed)
| # | Example | Description |
|---|---|---|
| 1 | kinematics_forward_inverse.py | Select a UR model, compute FK from joint angles, then compute all IK solutions |
๐ License
| # | Example | Description |
|---|---|---|
| 1 | license_info_example.py | Display license state, register a license, view all license properties |
๐ Protocol Reference
โก RTDE : Real-Time Data Exchange
RTDE is the recommended interface for high-frequency monitoring and control. It streams binary data at up to 500 Hz on port 30004 with a configurable recipe system.
What you can do:
- Subscribe to any combination of robot output variables (TCP pose, joint positions, forces, I/O states, temperatures, voltages, etc.)
- Write to robot input variables (digital outputs, analog outputs, integer/double/boolean registers)
- Stream at any frequency from 1 to 500 Hz (version 2 only)
- Use events (
output_data_received) for reactive, non-blocking data handling
Quick example:
from underautomation.universal_robots.ur import UR
from underautomation.universal_robots.connect_parameters import ConnectParameters
from underautomation.universal_robots.rtde.rtde_output_data import RtdeOutputData
from underautomation.universal_robots.rtde.rtde_input_data import RtdeInputData
from underautomation.universal_robots.rtde.rtde_input_values import RtdeInputValues
robot = UR()
params = ConnectParameters("192.168.0.1")
params.rtde.enable = True
params.rtde.frequency = 125
params.rtde.output_setup.add(RtdeOutputData.ActualTcpPose)
params.rtde.output_setup.add(RtdeOutputData.ActualTcpForce)
params.rtde.output_setup.add(RtdeOutputData.ActualDigitalOutputBits)
params.rtde.input_setup.add(RtdeInputData.InputIntRegisters, 24)
robot.connect(params)
@robot.rtde.output_data_received
def on_data(sender, event):
vals = robot.rtde.output_data_values
pose = vals.actual_tcp_pose
force = vals.actual_tcp_force
print(f"x={pose[0]:.3f} Fx={force[0]:.2f} N")
# Write back to the robot
inputs = RtdeInputValues()
inputs.input_int_registers.x24 = 42
robot.rtde.write_inputs(inputs)
robot.disconnect()
๐ Dashboard Server : Polyscope Legacy
The Dashboard Server runs on port 29999 and exposes a text-based command interface for program lifecycle control. Compatible with all CB-Series and e-Series robots running Polyscope.
What you can do:
- Load, play, stop, and pause programs
- Power on/off the robot arm and release brakes
- Read robot mode, safety status, and Polyscope version
- Show and close popup messages on the teach pendant
- Set operational mode (Manual / Automatic) for remote control
- Add messages to the robot controller log
Quick example:
from underautomation.universal_robots.ur import UR
from underautomation.universal_robots.connect_parameters import ConnectParameters
robot = UR()
params = ConnectParameters("192.168.0.1")
params.dashboard.enable = True
robot.connect(params)
robot.dashboard.power_on()
robot.dashboard.release_brake()
robot.dashboard.load_program("my_program.urp")
robot.dashboard.play()
mode = robot.dashboard.get_robot_mode()
print(f"Robot mode: {mode.value}")
robot.disconnect()
๐ REST API : PolyscopeX
The REST API is available on PolyscopeX robots (Polyscope version 9+) and provides a modern HTTP-based interface for robot and program control.
Quick example:
from underautomation.universal_robots.ur import UR
from underautomation.universal_robots.connect_parameters import ConnectParameters
robot = UR()
params = ConnectParameters("192.168.0.1")
params.rest.enable = True
robot.connect(params)
robot.rest.power_on()
robot.rest.brake_release()
robot.rest.load_program("my_program")
robot.rest.play()
state = robot.rest.get_program_state()
print(state.value)
robot.disconnect()
๐ Primary Interface
The Primary Interface (port 30001) streams binary data packets from the robot at ~10 Hz and also accepts URScript commands.
What you can do:
- Subscribe to robot mode, joint data, TCP cartesian position, tool data, safety data, and more
- Send URScript programs or commands to be executed immediately
- Read global variables declared in the loaded Polyscope program
Quick example:
from underautomation.universal_robots.ur import UR
from underautomation.universal_robots.connect_parameters import ConnectParameters
robot = UR()
params = ConnectParameters("192.168.0.1")
params.primary_interface.enable = True
robot.connect(params)
@robot.primary_interface.cartesian_info_received
def on_cart(sender, event):
c = robot.primary_interface.cartesian_info
print(f"x={c.x:.3f} y={c.y:.3f} z={c.z:.3f}")
robot.primary_interface.script.send('set_digital_out(0, True)')
robot.disconnect()
๐ SFTP : File Transfer over SSH
SFTP gives full file system access to the UR controller over SSH (port 22).
Default credentials: user=ur, password=easybot
What you can do:
- List, download, and upload files
- Enumerate all
.urpprograms and.installationfiles - Create and delete directories
Quick example:
params.ssh.enable = True
params.ssh.enable_sftp = True
params.ssh.username = "ur"
params.ssh.password = "easybot"
robot.connect(params)
programs = robot.sftp.enumerate_programs()
robot.sftp.download_file("/programs/my_prog.urp", "C:/backup/my_prog.urp")
robot.sftp.upload_file("C:/new_prog.urp", "/programs/new_prog.urp")
๐ฆพ Kinematics : Offline FK & IK
The SDK includes an offline kinematics engine with factory DH parameters for all UR models (UR3, UR5, UR10, UR3e, UR5e, UR7e, UR10e, UR12e, UR16e, UR15, UR18, UR20, UR30). No robot connection or license required.
Quick example:
import math
from underautomation.universal_robots.kinematics.kinematics_utils import KinematicsUtils
from underautomation.universal_robots.common.robot_models_extended import RobotModelsExtended
dh = KinematicsUtils.get_dh_parameters_from_model(RobotModelsExtended.UR10e)
# Forward kinematics: joint angles โ TCP pose
angles_rad = [math.radians(a) for a in [0, -90, 0, -90, 0, 0]]
result = KinematicsUtils.forward_kinematics(angles_rad, dh)
T = result.tool_transform # 4ร4 homogeneous matrix (flat list of 16 floats)
# Inverse kinematics: TCP pose โ all joint solutions
solutions = KinematicsUtils.inverse_kinematics(T, dh)
nearest = KinematicsUtils.get_nearest_solution(solutions, angles_rad)
print([math.degrees(v) for v in nearest])
๐ Resources
- Documentation & licensing: https://underautomation.com/universal-robots
- Also available in .NET, LabVIEW, and Unity
Made with โค๏ธ by the UnderAutomation team.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file underautomation_universalrobots-9.4.0.1.tar.gz.
File metadata
- Download URL: underautomation_universalrobots-9.4.0.1.tar.gz
- Upload date:
- Size: 572.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f77c08640c410d724e5c28d555eebfb0df3459b6628dd3594ecc97230ec3c540
|
|
| MD5 |
06eacef4c6fb98eb90f1826f89119a6e
|
|
| BLAKE2b-256 |
e7089949cc6d51580194491cda1696ef61dc3f8fbf9be4c2f8fb8bcc7c7a6afc
|
File details
Details for the file underautomation_universalrobots-9.4.0.1-py3-none-any.whl.
File metadata
- Download URL: underautomation_universalrobots-9.4.0.1-py3-none-any.whl
- Upload date:
- Size: 708.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8138e1d26e2dc9a902a7a9bc3672fdef2a9c8deb7e0c2dea9629357ef948ce2d
|
|
| MD5 |
5458ea30213c34b291915034c8462f8d
|
|
| BLAKE2b-256 |
227417ffd87f4c05f63ff4b65acfdd48ef10e0a4dc926ba75422049a038ce236
|