ur-rtde
ur-rtde is a Python interface for controlling and receiving data from Universal Robots (UR) manipulators using the Real-Time Data Exchange (RTDE) interface of the robot. It is a C++ library with Python bindings, providing fast and lightweight communication. The current version is 1.6.3, released on March 13, 2026. The library is actively maintained with a somewhat regular, though not strictly fixed, release cadence.
Common errors
-
RTDEControlInterface: Could not receive data from robot... read: End of file / RTDEControlInterface: Lost connection to robot... write: Broken pipe / Segmentation fault (core dumped)
cause Loss of network connection, underlying C++ library issues, or an unexpected state on the robot controller.fixCheck network cable and connections. Verify the robot's IP and network settings. Ensure no other applications are interfering with the RTDE ports. Restart the robot controller and your Python script. Consider running on a real-time OS. -
RTDEControlInterface: RTDE control script is not running!
cause The external control script required by the RTDEControlInterface is not active on the Universal Robot controller. This often happens after a connection drop and subsequent reconnection attempt.fixManually start or ensure the 'External Control' URCap (or equivalent PolyScope program) is running on the robot controller. Some `ur-rtde` functions automatically upload and start this script, but a manual check might be necessary after disconnections. -
RuntimeError: One of the RTDE input registers are already in use!
cause Attempting to write to an RTDE input register that is already being controlled by another RTDE client or a URCap on the robot.fixEnsure only one client is configured to control a specific input register at a time. Review all running programs on the robot and any other connected RTDE clients. -
Unpredictable Analog Output Voltage / Cannot read Digital Input (values are incorrect or always 0)
cause Misunderstanding the scaling or behavior of analog/digital I/O functions, or potential library-specific quirks in certain versions.fixConsult the specific `ur-rtde` version's API documentation and examples for I/O handling. Verify the robot's I/O configuration in PolyScope. Test with simpler, known-good I/O examples if available.
Warnings
- breaking The RTDE protocol may be updated by Universal Robots. New UR software versions can introduce protocol changes, potentially leading to incompatibility with older `ur-rtde` versions or requiring clients to explicitly request compatible protocol versions.
- gotcha The `RTDEControlInterface` is explicitly stated as *not thread-safe*. Concurrent calls from multiple threads without proper synchronization can lead to unpredictable behavior, including connection issues or robot control errors.
- gotcha For precise and safe real-time control, particularly under high system load, `ur-rtde` highly recommends running on an operating system with a real-time kernel.
- gotcha Installation via `pip` can fail if your `pip` version is older than 19.3.
- gotcha Incorrect network configuration (e.g., robot and PC not in the same IP subnet, active firewalls) is a frequent cause of connection failures.
Install
-
pip install ur-rtde
Imports
- RTDEControlInterface
from rtde_control import RTDEControlInterface
- RTDEReceiveInterface
from rtde_receive import RTDEReceiveInterface
- RTDEIOInterface
from rtde_io import RTDEIOInterface
Quickstart
import rtde_control
import rtde_receive
import rtde_io
import time
# Replace with your robot's IP address
ROBOT_IP = os.environ.get('UR_ROBOT_IP', '192.168.1.10')
try:
# Initialize RTDE interfaces
rtde_r = rtde_receive.RTDEReceiveInterface(ROBOT_IP)
rtde_c = rtde_control.RTDEControlInterface(ROBOT_IP)
rtde_io_ = rtde_io.RTDEIOInterface(ROBOT_IP)
if not rtde_r.isConnected():
print(f"Could not connect to RTDE Receive interface at {ROBOT_IP}")
exit()
if not rtde_c.isConnected():
print(f"Could not connect to RTDE Control interface at {ROBOT_IP}")
exit()
print("Successfully connected to the robot.")
# Start synchronization
rtde_r.startFileSynchronization("") # No recipe file for quickstart, use default
rtde_c.sendStart()
# Example: Read a robot state (joint positions)
print(f"Current Joint Positions: {rtde_r.getActualQ()}")
# Example: Send a simple move command (blocking)
# NOTE: Ensure the robot is in 'Remote Control' mode and 'External Control' URCap is running on the robot.
# This example assumes the robot is ready to receive commands.
# Make sure this move is safe for your robot setup.
# target_q = [-1.5, -1.8, 1.8, -1.8, -1.5, 0.0] # Example joint configuration in radians
# if rtde_c.moveJ(target_q, 0.5, 0.3): # speed, acceleration
# print("Robot moved to target joint configuration.")
# else:
# print("Failed to move robot.")
# Example: Set a digital output
# rtde_io_.setStandardDigitalOut(0, True)
# print("Set digital output 0 to True")
# time.sleep(1)
# rtde_io_.setStandardDigitalOut(0, False)
# print("Set digital output 0 to False")
finally:
# Stop RTDE communication and disconnect
if 'rtde_c' in locals() and rtde_c.isConnected():
rtde_c.sendPause()
rtde_c.disconnect()
print("Disconnected RTDE Control Interface.")
if 'rtde_r' in locals() and rtde_r.isConnected():
rtde_r.disconnect()
print("Disconnected RTDE Receive Interface.")