← Robot hub
ROBOT / ABB / RAPID

BRAND.00 / IRC5 + OMNICORE · RAPID

ABB RAPID

The structured, Pascal-like language that programs ABB industrial robots.

ABB introduced RAPID in 1994 with the S4 controller, and it is still the language of the IRC5 and OmniCore controllers. It is structured and strongly typed, closer to Pascal than to BASIC. A program is built from modules, execution starts at a routine called main, and data is declared apart from the instructions that use it. A single Move line says everything about a motion: where to go, how fast, how close to pass the point, and with which tool.

First IRB
1974
ASEA, part of ABB since 1988, presented the IRB 6: ABB calls it the first microprocessor-controlled, all-electric industrial robot. It carried 6 kg.
RAPID introduced
1994
Arrived with the S4 controller and replaced the older ARLA language. RAPID written for S4 still reads almost unchanged on OmniCore.
Current platform
OmniCore
Controller family launched in 2018. ABB announced in 2024 that it replaces IRC5, with IRC5 phased out from June 2026.
Sim environment
RobotStudio
Offline programming with a virtual controller that runs the same RobotWare as the real cabinet.

ABB is one of the four big industrial robot makers, with FANUC, KUKA and Yaskawa. For a programmer, what sets it apart is RobotStudio, whose virtual controller runs the same RobotWare as the real cabinet, and the way RAPID, the controller (IRC5 or OmniCore) and the SafeMove safety option are designed to work together.

Heritage
Half a century of IRBs

The IRB name runs from the 1974 IRB 6 to today's IRB 1010 and the OmniCore generation. A RAPID program written for an S4 reads almost the same on OmniCore.

Controller
IRC5 to OmniCore

IRC5 (2004) is still in a great many cells, and ABB has announced its phase-out from June 2026. OmniCore runs the same language on RobotWare 7.

Tooling
RobotStudio + RobotWare

RobotStudio is ABB's offline programming and simulation tool. Its virtual controller runs the RobotWare of the real robot, so you can check code, reach and cycle time before the cell exists.

CLASSIC IRB · 6-axis articulatedenclosed cells · fenced
IRB 1200
payload
5 to 7 kg
reach
703 to 901 mm

Compact pick-and-place, machine tending

IRB 1600
payload
6 to 10 kg
reach
1.20 to 1.45 m

Arc welding, material handling

IRB 2600
payload
12 to 20 kg
reach
1.65 to 1.85 m

Welding, dispensing, assembly

IRB 4600
payload
20 to 60 kg
reach
2.05 to 2.55 m

Handling, palletising, machine tending

IRB 6700
payload
150 to 300 kg
reach
2.60 to 3.20 m

Spot welding and heavy handling

IRB 7600
payload
150 to 500 kg
reach
2.55 to 3.50 m

Heavy handling, for example car bodies in the body shop

COLLABORATIVE · works alongside peopleISO/TS 15066 collaborative operation · risk assessment per cell
YuMi · IRB 14000
payload
0.5 kg / arm
reach
0.56 m

Dual-arm small-parts assembly

14 axes · 38 kg total · IP30

Single-arm YuMi · IRB 14050
payload
0.5 kg
reach
0.56 m

Bench-top precision assembly

7 axes · 9.5 kg · 0.02 mm repeatability

GoFa · CRB 15000
payload
5 / 10 / 12 kg
reach
0.95 to 1.52 m

Cobot for material handling and machine tending

IP54 · power and force limiting

SWIFTI · CRB 1100
payload
4 kg
reach
475 / 580 mm

Industrial-speed cobot: slows and stops as a person comes close

Up to 5 m/s TCP · 0.01 mm repeatability · SafeMove + safety laser scanner · now phased out

Payloads and reaches are the values ABB publishes on its product pages and datasheets. The usable workspace is smaller than the reach circle: there is a dead zone close to the base, and at full stretch the wrist cannot reach every orientation. Read the payload diagram as well as the payload figure, because a gripper whose centre of gravity sits far from the flange takes a large share of the rating.

FeatureIRC5 (legacy fleet)OmniCore (current)
GenerationLaunched 2004 · phase-out from June 2026, very large installed baseFamily launched 2018 · ABB's current controller
Cabinet form factorSingle and dual cabinet, compact IRC5C, panel-mountedE10, C30, C90XT, V250XT, V400XT
Motion controlQuickMove and TrueMove (first released 1994; second generation from 2009)ABB's 2024 platform: up to 25% faster and up to 20% less energy than the previous controller, by ABB's figures
SafetySafeMove2 option (PL d, Cat. 3)SafeMove option (PL d, Cat. 3)
ConnectivityFieldbus options: PROFINET, EtherNet/IP, DeviceNet, PROFIBUS and othersPROFINET and EtherNet/IP among the fieldbus options
Programming surfaceRAPID · FlexPendantRAPID · FlexPendant, plus Wizard block programming for cobots
SimulationRobotStudio (RobotWare 5 or 6)RobotStudio (RobotWare 7)
Most RAPID moves from IRC5 to OmniCore unchanged. I/O configuration, system parameters and a few instructions change between RobotWare 6 and 7, so plan the migration and test it in RobotStudio first.

Every classic IRB has the same six-axis articulated layout. ABB numbers the axes 1 to 6 from the base to the flange (a jointtarget stores them as rax_1 to rax_6), and the world frame is right-handed with +Z up, as ISO 9787 defines. Hover or click a part to see what it does.

TCP+X+Z+Y (in)ISO 9787: right-handed, world +Z upJ1J2J3J4-6
TCP

Tool centre point: the point the robot actually positions, usually the tip of the gripper or torch, not the flange.

Modules and routines

A program is a set of modules (MODULE ... ENDMODULE). PROC is a procedure, FUNC returns a value, TRAP answers an interrupt. Execution starts in the routine named main. System modules hold data every program shares, such as tooldata, and stay loaded when you load a new program.

MODULE MainModule
  PROC main()
    ! ...
  ENDPROC
ENDMODULE

Motion types

MoveJ moves all axes together: fastest, and the TCP path is a curve. MoveL keeps the TCP on a straight line. MoveC runs an arc through a circle point. MoveAbsJ goes to axis angles, so a home move never meets a configuration problem. Every move takes target, speeddata, zonedata and tooldata, in that order.

MoveJ pHome, v1000, z50, tGripper;
MoveL pPick, v200, fine, tGripper;

Coordinate systems

The TCP is defined by tooldata. Targets are stored in a work object (wobjdata), which holds a user frame (the fixture) and an object frame (the part on it). Re-teach the user frame after a fixture moves and every point in it follows. Without \WObj a move uses wobj0, which coincides with the world frame.

MoveL pPick, v500, fine, tGripper \WObj:=wPallet;

Data types

robtarget: position [x,y,z] in mm, orientation as a quaternion, axis configuration [cf1,cf4,cf6,cfx] and external axes. jointtarget: axis angles. speeddata runs from v5 to v7000 plus vmax; v1000 is 1000 mm/s at the TCP and 500 degrees/s reorientation. zonedata: fine, then z0 to z200, where z10 allows a 10 mm TCP zone.

CONST robtarget pPick:=
  [[800,0,300],[0,0,1,0],
   [0,0,0,0],[9E9,9E9,9E9,9E9,9E9,9E9]];

CONST, VAR and PERS

CONST never changes. A VAR gets its initial value back when the program is reset. A PERS keeps its current value, written back into the module, through resets and restarts. Taught targets are usually CONST, tooldata, wobjdata and counters PERS, scratch values VAR.

CONST num nLayers:=6;
VAR num nTry:=0;
PERS num nPartsDone:=0;

I/O handling

SetDO and ResetDO write digital outputs, PulseDO pulses one, SetGO writes a number to a group of bits. WaitDI blocks until an input has a value; give it \MaxTime in production code. RAPID uses the signal names from the I/O configuration, such as doGripper and diPartReady.

SetDO doGripper, 1;
WaitDI diPartReady, 1 \MaxTime:=10;

Program flow and interrupts

IF/ELSEIF/ELSE, FOR, WHILE and TEST/CASE. An interrupt takes three steps: CONNECT an intnum to a TRAP, order the event with ISignalDI, and IDelete it when you are done. TRAPs are for process events like a vacuum loss. E-stops and guard doors belong to the safety system, not to RAPID.

CONNECT iPartLost WITH tPartLost;
ISignalDI diVacuumOk, 0, iPartLost;

RAPID is Pascal in a hard hat

PROC for procedure, FOR ... FROM ... TO ... DO with its own ENDFOR, and a data type written before the name with no colon (VAR num i;). RAPID even declares the FOR counter for you. The shape of the program is the same, so anyone who has read Pascal can follow RAPID.

Pascal · 1970
procedure Cycle;
var i: integer;
begin
  for i := 1 to 5 do
    WriteLn('step ', i);
end;
RAPID · 1994
PROC Cycle()
  FOR i FROM 1 TO 5 DO
    TPWrite "step " + ValToStr(i);
  ENDFOR
ENDPROC

These two motion types make up most of any program. Same start, same end, different path, because MoveJ interpolates in joint space and MoveL in Cartesian space. Toggle below and watch the TCP trace.

startend
MoveJ: curved TCP path, joints move evenly
MoveL: straight TCP line, joint speeds vary
J1 100° · J2 102°
When to use MoveJ
Moves through free air between stations, and any move where the path touches nothing. All axes arrive together, so it is the fastest move and the gentlest on the gearboxes. Keep it clear of fixtures: the curve it draws changes with the start configuration.
When to use MoveL
The last stretch into a pick or place, weld seams, glue beads, and any move through a narrow opening. Axis speeds change along the line to keep the TCP straight, and a line that passes near a wrist singularity (axis 5 close to 0 degrees) makes axes 4 and 6 spin fast or stops the robot with an error.

In RAPID the third argument of a Move instruction is its zonedata. fine stops the robot at the point. z0…z200 lets the TCP cut the corner inside a zone of that radius in mm and carry on without stopping, which is where cycle time is won. The controller shrinks a zone that is larger than half the move, and the instructions after a zone point (SetDO, WaitTime) run before the robot reaches the point.

z40
P1P2 (corner)P3misses P2 by 18.2 mm
Taught path (fine: full stop at P2)
Executed path with a 40 mm zone
ABB
zonedata, mm
z40
KUKA
$APO.CDIS, mm
$APO.CDIS=40 … LIN P2 C_DIS
FANUC
CNT 0 to 100, not mm
CNT n: size depends on speed
UR
r= blend radius, m
r=0.040

Every vendor has the same idea under another name: ABB zonedata (radius in mm), KUKA $APO.CDIS with C_DIS (distance in mm), FANUC CNT 0 to 100 (a degree of rounding, not a distance), UR the blend radius r in metres. None of them draws a true circular arc: each controller plans its own smooth transition inside the zone.

When you write MoveAbsJ jHome, v1000, fine, tool0;, the controller runs forward kinematics: it walks the chain from base to flange and works out where the TCP ends up. There is exactly one answer, which is why a jointtarget never has a configuration problem. The widget below is a three-link planar version of the same calculation; move the sliders and watch the TCP pose.

+X+Yworld (mm)J1J2J3TCP
45°
-160°0°160°
-60°
-120°0°120°
-30°
-150°0°150°
TCP pose
X321.7 mm
Y39.0 mm
φ(tool pitch about Z)-45.0°
d(distance from base)324.0 mm
InstructionCategoryPurposeExample
MoveJMotionJoint move: every axis starts and stops together, so the TCP path is a curve you do not control. Fastest way through free air.MoveJ pHome, v1000, z50, tGripper;
MoveLMotionLinear move: the TCP runs a straight line at the speeddata TCP speed (mm/s). Use it for the last approach, the pick and the retreat.MoveL pPick, v200, fine, tGripper;
MoveCMotionCircular move from the current position through a circle point to the end point. Keep the three points well apart or the arc is badly defined.MoveC pMid, pEnd, v300, z10, tGlue;
MoveAbsJMotionMove to a jointtarget (axis angles in degrees). No configuration choice is involved, which makes it the safe way to a home or service position.MoveAbsJ jHome, v1000, fine, tool0;
MoveLDOMotionLinear move that sets a digital output in the middle of the corner path of its zone point.MoveLDO p20, v1000, z30, tool0, doGlue, 1;
OffsMotionFunction: a copy of a robtarget shifted x, y, z mm in the work object frame. The usual way to make approach points and pallet grids from one taught point.MoveL Offs(pPick, 0, 0, 100), v500, z20, tGripper;
RelToolMotionFunction: a robtarget shifted (and optionally rotated) in the tool frame, for example straight back along the tool Z axis.MoveL RelTool(pPick, 0, 0, -100), v500, z20, tGripper;
SetDOI/OWrite a digital output to 0 or 1.SetDO doGripper, 1;
ResetDOI/OSet a digital output to 0.ResetDO doGripper;
PulseDOI/OPulse a digital output. The default pulse is 0.2 s; \PLength sets another length.PulseDO \PLength:=0.5, doEject;
SetGOI/OWrite a number to a group output (several bits read as one integer), for example a recipe number to the PLC.SetGO goRecipe, 12;
WaitDIWaitWait until a digital input has a value. Add \MaxTime so a dead sensor raises an error you can handle instead of a silent stop.WaitDI diPartReady, 1 \MaxTime:=10;
WaitUntilWaitWait until any boolean expression is TRUE.WaitUntil diClampA = 1 AND diClampB = 1;
WaitTimeWaitWait a number of seconds. Motion queued before it carries on.WaitTime 0.5;
IFFlowConditional with optional ELSEIF and ELSE.IF nCount > 10 THEN ... ENDIF
FORFlowCounted loop. The loop variable is declared by the FOR itself and only exists inside it.FOR i FROM 1 TO 5 DO ... ENDFOR
WHILEFlowLoop while a condition is TRUE, tested before each pass.WHILE bRun DO ... ENDWHILE
TESTFlowSwitch on a value: CASE lists, DEFAULT for the rest.TEST nMode CASE 1: ... DEFAULT: ... ENDTEST
PROCStructureDeclare a procedure. Call it by name with no brackets: Pick; or PickAt 150;PROC PickAt(num zHeight) ... ENDPROC
FUNCStructureDeclare a function that returns a value. Function calls take brackets.FUNC num Add(num a, num b) ... ENDFUNC
TRAPStructureInterrupt routine. It runs when its interrupt fires, then the program carries on where it was.TRAP tPartLost ... ENDTRAP
CONSTStructureConstant data. Taught positions are often CONST so a program cannot change them by accident.CONST robtarget pPick:=[[800,200,300],[0,0,1,0],[0,0,0,0],[9E9,9E9,9E9,9E9,9E9,9E9]];
VARStructureVariable. Gets its initial value back when the program is reset (program pointer to Main) or the module is reloaded.VAR num nCount:=0;
PERSStructurePersistent: the current value is written back into the module, so it survives a program reset and a restart. Tooldata, wobjdata and part counters are usually PERS.PERS num nPartsDone:=0;
CONNECTSystemBind an intnum interrupt identity to a TRAP routine.CONNECT iPartLost WITH tPartLost;
ISignalDISystemOrder an interrupt when a digital input changes to a value.ISignalDI diVacuumOk, 0, iPartLost;
IDeleteSystemCancel an interrupt and free its identity. Do it before you CONNECT the same intnum again.IDelete iPartLost;
ConfLSystemTurn configuration supervision for linear moves on or off. With \Off the robot may finish a MoveL in a different axis configuration from the one taught.ConfL \On;
VelSetSystemScale programmed speed by a percentage and cap TCP speed in mm/s for all following moves.VelSet 50, 800;
AccSetSystemReduce acceleration (percent) and its ramp (percent), for a heavy or loose part.AccSet 50, 50;
RAPID.EDITORPROC Main()
NOW:— idle —
NEXT:MoveJ pHome, v1000, z50, tGripper;
XY.WORKSPACE3 targets · grid 100mm
SIM TIME
00:00.00
TCP [X,Y,Z]
600, 0, 800
SPEED
0 mm/s
DIGITAL OUT
doGripper
DIGITAL IN
(none)
FOR, IF, WHILE, TEST/CASE, REPEAT, PROC + RETURN, INOUT, FUNC, assignment, Offs() / RelTool() (nested), local VAR, and warnings supported.
00:00.00STATE: idle00:03.95