BRAND.05 / CB3 + e-Series
The Python-flavoured scripting language that drives every UR collaborative robot.
URScript is the underlying language used by every Universal Robots cobot — UR3, UR5, UR10, UR16, and the e-Series. It looks and feels like Python: indentation is cosmetic, blocks are closed with a literal end, and program flow uses if / elif / else, for / in / range, and while. Motion is expressed with movej / movel / movep / movec, I/O through set_digital_out() / get_digital_in(), and timing through sleep().
A URScript program is plain text that runs top-to-bottom. Functions are defined with def name(): … end and called like Python. The entry point is typically a main() function called at the end of the file.
def pick(): movel(p_pick, a=1.2, v=0.25) end def main(): pick() end main()
movej is joint motion (point-to-point, fastest). movel is linear (Cartesian) at the active TCP speed. movep adds circular blends between linear segments. movec is a 3-point arc.
movej(p_home, a=1.4, v=1.05) movel(p_pick, a=1.2, v=0.25) movec(p_via, p_to, a=1.2, v=0.25, r=0)
A pose is a 6-vector — XYZ in metres and rotation in axis-angle form (rx, ry, rz). Pose helpers like pose_add / pose_inv / pose_trans compose them. Variables can hold poses or simple numbers.
p_pick = p[0.4, 0.0, 0.2, 0, 3.14, 0] p_drop = pose_add(p_pick, p[0.2, 0.0, 0, 0, 0, 0])
set_tcp(pose) defines the active tool centre point relative to the flange. set_payload(mass, cog) tells the controller what the tool weighs so dynamics are correct.
set_tcp(p[0,0,0.15,0,0,0]) set_payload(1.5, [0,0,0.05])
set_digital_out(n, True|False) drives a standard digital output. get_digital_in(n) reads an input as a boolean. Tool-flange variants use set_tool_digital_out / get_tool_digital_in.
set_digital_out(1, True) if get_digital_in(0): movel(p_pick, a=1.2, v=0.25) end
if cond: ... elif: ... else: ... end. for var in range(n): ... end. while cond: ... end. def name(): ... end. Every block is closed with a literal "end" keyword (not Python indent).
for i in range(3):
if get_digital_in(0):
movel(p_pick, a=1.2, v=0.25)
end
end| Instruction | Category | Purpose | Example |
|---|---|---|---|
| movej | Motion | Joint move (linear in joint space, fastest, path not constrained) | movej(p[0.4,0.0,0.3,0,3.14,0], a=1.4, v=1.05) |
| movel | Motion | Linear (Cartesian) move at the active TCP speed | movel(p[0.4,0.1,0.3,0,3.14,0], a=1.2, v=0.25) |
| movep | Motion | Linear move with constant tool speed and circular blends | movep(p[0.4,0.1,0.3,0,3.14,0], a=1.2, v=0.25, r=0.05) |
| movec | Motion | Circular move via a via-point and end-point | movec(p_via, p_to, a=1.2, v=0.25, r=0) |
| speedj | Motion | Joint speed command — accelerate to a joint velocity vector | speedj([0,0,0,0,0,0.2], 0.5, 1.0) |
| speedl | Motion | TCP speed command — accelerate to a Cartesian velocity vector | speedl([0.1,0,0,0,0,0], 0.25, 1.0) |
| stopj | Motion | Decelerate joint motion to a stop with the given acceleration | stopj(2.0) |
| stopl | Motion | Decelerate Cartesian motion to a stop with the given acceleration | stopl(2.0) |
| set_tcp | Frames | Set the active tool centre point pose (relative to flange) | set_tcp(p[0,0,0.15,0,0,0]) |
| set_payload | System | Set the payload mass (kg) and centre of gravity | set_payload(1.5, [0,0,0.05]) |
| set_digital_out | I/O | Set a standard digital output (n, True|False) | set_digital_out(1, True) |
| get_digital_in | I/O | Read a standard digital input — returns True or False | if get_digital_in(0): |
| set_tool_digital_out | I/O | Set a tool-flange digital output (n, True|False) | set_tool_digital_out(0, True) |
| get_tool_digital_in | I/O | Read a tool-flange digital input — returns True or False | if get_tool_digital_in(0): |
| set_analog_out | I/O | Set a standard analog output to a value in [0..1] | set_analog_out(0, 0.5) |
| get_analog_in | I/O | Read a standard analog input (Volts or mA) | v = get_analog_in(0) |
| rq_open | I/O | Robotiq gripper helper — fully open the gripper | rq_open() |
| rq_close | I/O | Robotiq gripper helper — fully close the gripper | rq_close() |
| sleep | Wait | Pause execution for N seconds (floating-point allowed) | sleep(0.5) |
| sync | Wait | Wait for the current motion to finish before continuing | sync() |
| if | Flow | Conditional branch — if cond: ... [elif]: ... [else]: ... end | if get_digital_in(0): |
| elif | Flow | Else-if branch inside an if block | elif count > 5: |
| else | Flow | Else branch inside an if block | else: |
| while | Flow | Pre-test loop — while cond: ... end | while count < 5: |
| for | Flow | Counted loop — for var in range(n): ... end | for i in range(3): |
| def | Flow | Define a sub-routine (function) — def name(args): ... end | def pick(): |
| end | Flow | Closes a control block (if / while / for / def) | end |
| break | Flow | Exit the innermost loop early | break |
| continue | Flow | Skip to the next loop iteration | continue |
| return | Flow | Return from a function (optionally with a value) | return |
| halt | Flow | Halt program execution (operator must restart) | halt |
| global | Variable | Declare a variable as program-global | global count = 0 |
| p[…] | Pose | Pose literal — [x, y, z, rx, ry, rz] in metres / axis-angle | p[0.4, 0.1, 0.3, 0, 3.14, 0] |
| pose_add | Pose | Add two poses (translation + rotation composed) | pose_add(p_base, p[0,0,0.05,0,0,0]) |
| pose_inv | Pose | Invert a pose | pose_inv(p_tool) |
| pose_trans | Pose | Compose two poses (transform p_to by p_from) | pose_trans(p_base, p_offset) |
| get_actual_tcp_pose | Pose | Read the current TCP pose in the base frame | p_now = get_actual_tcp_pose() |
| get_actual_joint_positions | Pose | Read the current joint positions [j0..j5] in radians | q = get_actual_joint_positions() |
| popup | System | Show a popup message on the teach-pendant | popup("Cycle done", "Info", False, False, False) |
| textmsg | System | Print a message to the controller log | textmsg("step=", i) |
| powerdown | System | Power down the robot arm at the end of a program | powerdown() |
| # | Misc | Comment to end of line (Python convention) | # pick up the part |