Skip to content

underautomation/UniversalRobots.py

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

41 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Universal Robots Communication SDK for Python

UnderAutomation Universal Robots SDK

PyPI Python Platform License

πŸ€– 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:

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 .urp programs and .installation files
  • 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


Made with ❀️ by the UnderAutomation team.

About

πŸš€πŸ Python library for seamless communication with your Universal Robots cobot. Supports RTDE, URScript execution, Dashboard Server, SFTP, SSH, and more!

Topics

Resources

Stars

13 stars

Watchers

2 watching

Forks

Contributors

Languages