An industrial robot is a reprogrammable, multi-axis manipulator that positions a tool along a controlled trajectory. Four architectures dominate factory floors: the articulated arm, the SCARA, the Delta (parallel), and the Cartesian gantry. Each trades off reach, speed, payload, and stiffness in a different way. The kinematic structure decides which jobs a robot can do well, how its inverse kinematics (IK) is solved, and how you must tune its control loop. This guide covers the mechanics, the math, ROS2 integration, and a selection workflow.
Quick Takeaways
- Articulated 6-axis arms offer the widest workspace and orientation freedom, with payloads from 3 kg to over 1,000 kg and repeatability near ±0.02 mm.
- SCARA robots deliver the fastest planar pick-and-place for light loads (cycle times under 0.4 s) with a rigid Z-axis for insertion.
- Delta robots use lightweight parallel arms to hit 200+ picks per minute, but carry payloads under roughly 8 kg.
- Gantry (Cartesian) robots scale to multi-meter workspaces with closed-form kinematics and the highest stiffness, at the cost of footprint and speed.
| Type | DOF | Typical Payload | Repeatability | Speed | Workspace Shape | Relative Cost |
|---|---|---|---|---|---|---|
| Articulated arm | 4-7 | 3-1,000+ kg | ±0.02-0.1 mm | Medium | Spherical shell | Medium-High |
| SCARA | 4 | 1-20 kg | ±0.005-0.02 mm | Very high (planar) | Cylindrical, flat | Medium |
| Delta | 3-4 | 0.1-8 kg | ±0.05-0.1 mm | Highest | Inverted dome/cylinder | Medium |
| Gantry | 2-6 | 1-1,000+ kg | ±0.01-0.05 mm | Low-Medium | Rectangular box | Low-Very High |
Kinematic Foundations
Every industrial robot reduces to two mapping problems:
- Forward kinematics (FK): joint variables q → end-effector pose T
- Inverse kinematics (IK): pose T → joint variables q
Serial robots (arm, SCARA, gantry) have easy FK and harder IK. Parallel robots (Delta) reverse this: IK is closed-form, FK needs more work.
The standard tool for serial chains is the Denavit-Hartenberg (DH) convention. Each joint i contributes a homogeneous transform:
T(i-1,i) = Rot_z(θi) · Trans_z(di) · Trans_x(ai) · Rot_x(αi)
| cosθ -sinθ·cosα sinθ·sinα a·cosθ |
= | sinθ cosθ·cosα -cosθ·sinα a·sinθ |
| 0 sinα cosα d |
| 0 0 0 1 |
T(0,n) = T(0,1) · T(1,2) · ... · T(n-1,n)
The velocity mapping uses the Jacobian J(q):
ẋ = J(q) · q̇
τ = Jᵀ(q) · F (static force/torque mapping)
When det(J) = 0, the robot sits at a singularity and loses a degree of freedom in Cartesian space. Every architecture below has its own singularity map, and your path planner must avoid it.
Articulated Robot Arms (6-Axis)
The articulated arm chains revolute joints in series, usually with a spherical wrist (three joint axes intersecting at one point). It mimics a human arm and reaches around obstacles at arbitrary orientations.
Mechanical Layout
- Joints 1-3 (the “arm”): position the wrist center
- Joints 4-6 (the “wrist”): orient the tool
- Actuation: servo motors with harmonic drive or cycloidal reducers (gear ratios 50:1 to 160:1), plus 17- to 23-bit absolute encoders
- Typical supply: 200-480V AC, three-phase, via a cabinet controller
Inverse Kinematics: Decoupling the Wrist
A spherical wrist lets you split IK into position and orientation. Given the target pose with wrist center p_wc:
p_wc = p_tool - d6 · R_tool · [0, 0, 1]ᵀ
θ1 = atan2(p_wc_y, p_wc_x)
r = sqrt(p_wc_x² + p_wc_y²) - a1
s = p_wc_z - d1
D = (r² + s² - a2² - d4²) / (2 · a2 · d4) // law of cosines
θ3 = atan2(±sqrt(1 - D²), D) // elbow up / elbow down
θ2 = atan2(s, r) - atan2(d4·sinθ3, a2 + d4·cosθ3)
R(3,6) = R(0,3)ᵀ · R_tool // solve θ4, θ5, θ6 from Euler angles
The ± in θ3 produces up to 8 valid solutions per pose (shoulder, elbow, and wrist flips). Pick the one closest to the current joint state to avoid large jumps.
Singularities to Avoid
- Shoulder: wrist center on the axis of joint 1
- Elbow: arm fully extended or folded (
θ3 = 0orπ) - Wrist: joints 4 and 6 aligned (
θ5 = 0)
Best-Fit Applications
Arc welding, painting, machine tending, palletizing, and assembly in unstructured cells.
SCARA Robots
SCARA (Selective Compliance Assembly Robot Arm) uses two parallel-axis revolute joints for planar motion plus a prismatic Z-axis and a rotating tool. It is compliant in X-Y (for self-aligning insertion) and extremely stiff in Z.
Planar 2-Link IK
For link lengths L1, L2 and a target (x, y):
c2 = (x² + y² - L1² - L2²) / (2 · L1 · L2)
θ2 = atan2(±sqrt(1 - c2²), c2) // lefty / righty
θ1 = atan2(y, x) - atan2(L2·sinθ2, L1 + L2·cosθ2)
z = Z joint (direct)
θ4 = ψ - θ1 - θ2 // tool yaw compensation
Reachability requires |L1 - L2| ≤ sqrt(x² + y²) ≤ L1 + L2. Outside this annulus, there is no solution.
Why SCARA Wins at Speed
The heavy motors sit at the base, so the moving mass stays low. Typical specs: 0.3-0.5 s for a 25-300-25 mm Adept cycle, ±0.01 mm repeatability, and 4 DOF only. This simplicity gives a smaller controller, lower cost, and easy tuning.
Best-Fit Applications
PCB insertion, screw driving, small-part assembly, dispensing, and packaging.
Delta (Parallel) Robots
A Delta robot hangs three (sometimes four) lightweight arms from a fixed base. Each arm is a driven upper link plus a parallelogram of lower rods that holds the platform orientation constant. Motors stay on the base, so moving inertia is tiny.
Closed-Form IK
For base radius R_b, platform radius R_p, upper arm L_u, lower arm L_l, and target (x, y, z), solve each arm i at azimuth φi = 0°, 120°, 240°:
// Rotate the target into arm i's plane
x_i = x·cosφi + y·sinφi
y_i = -x·sinφi + y·cosφi
// Effective offset
a = x_i + R_p - R_b
// Distance constraint (sphere-circle intersection)
// L_l² = a² + y_i² + (z - L_u·sinθi)² ... reduced to:
E = 2·L_u·(y_i + R_p·0 - ...) // see full derivation below for implementation
In practice, use the well-known implementation (Paul Hoeller / Trossen-style) below:
import math
# Delta robot geometry (mm) -- measure these on your hardware
F = 115.47 # base triangle side length
E = 457.30 # platform triangle side length
RF = 112.0 # upper arm length
RE = 232.0 # lower arm (parallelogram) length
SQRT3 = math.sqrt(3.0)
TAN30 = 1.0 / SQRT3
def _angle_yz(x0, y0, z0):
"""Solve theta for one arm in its YZ plane. Returns degrees or None."""
y1 = -0.5 * TAN30 * F # base joint position (shifted to the YZ plane)
y0 -= 0.5 * TAN30 * E # shift target to platform joint center
# z = a + b*y is the plane intersection with the lower-arm sphere
a = (x0*x0 + y0*y0 + z0*z0 + RF*RF - RE*RE - y1*y1) / (2.0 * z0)
b = (y1 - y0) / z0
d = -(a + b*y1)**2 + RF*(b*b*RF + RF) # discriminant
if d < 0:
return None # target outside the workspace
yj = (y1 - a*b - math.sqrt(d)) / (b*b + 1)
zj = a + b*yj
theta = math.degrees(math.atan2(-zj, (y1 - yj)))
return theta + (180.0 if yj > y1 else 0.0)
def delta_ik(x, y, z):
"""Return (theta1, theta2, theta3) in degrees, or None if unreachable."""
c, s = -0.5, SQRT3 / 2.0 # cos/sin of 120 degrees
t1 = _angle_yz(x, y, z)
t2 = _angle_yz(x*c + y*s, y*c - x*s, z) # rotate +120 deg
t3 = _angle_yz(x*c - y*s, y*c + x*s, z) # rotate -120 deg
if None in (t1, t2, t3):
return None
return t1, t2, t3
Note that z is negative below the base in this convention. Validate the geometry constants against your own CAD before trusting the output.
Performance Profile
- Acceleration: 10-15 g on the platform
- Speed: 200-300 picks per minute with vision tracking
- Limits: payload under about 8 kg, small workspace relative to footprint
- Control: high-rate servo loops (typically 1-4 kHz) because of the high accelerations
Best-Fit Applications
Food and pharma packaging, conveyor tracking, sorting, and light-load pick-and-place.
Gantry (Cartesian) Robots
A gantry robot moves linearly along orthogonal axes: X, Y, and Z, with optional rotary wrist axes. The kinematics is trivial:
x = q1
y = q2
z = q3
J = I (identity) // no singularities in the linear subspace
Structural Variants
- Overhead gantry: bridge spanning a work area, supported on two sides
- Cantilever: single-sided support, compact but less stiff
- Moving-bridge / dual-drive: requires gantry squaring (synchronizing two Y motors to prevent racking)
Drive Options
| Drive Type | Accuracy | Speed | Max Stroke | Notes |
|---|---|---|---|---|
| Ball screw | ±0.01 mm | Low-Med | ~3 m | Best precision, critical-speed limit |
| Rack & pinion | ±0.05-0.1 mm | High | 20+ m | Backlash needs preload |
| Belt drive | ±0.1-0.2 mm | High | 10+ m | Light loads, stretch compensation |
| Linear motor | ±0.001 mm | Very high | 5 m | Costly, needs cooling |
Best-Fit Applications
CNC machine loading, 3D printing at scale, palletizing, warehouse storage, and large-format inspection.
Side-by-Side Comparison
| Criterion | Articulated | SCARA | Delta | Gantry |
|---|---|---|---|---|
| Reach flexibility | Excellent | Planar only | Limited dome | Box-shaped |
| Orientation control | Full 6-DOF | Yaw only | Yaw only (4-DOF) | Optional wrist |
| Max cycle speed | Medium | High | Very high | Low-Medium |
| Payload-to-weight | Medium | Medium | Low | High |
| Stiffness | Medium | High (Z) | Medium | Very high |
| Floor footprint | Small | Small | Medium (overhead) | Large |
| IK complexity | Multi-solution | 2-solution | Closed-form | Trivial |
| Programming effort | High | Low | Medium | Low |
ROS2 Integration
All four types integrate through ros2_control, which separates hardware interfaces from controllers. A typical stack:
- URDF/Xacro describes links, joints, and limits
ros2_controlhardware interface talks to drives (EtherCAT, CANopen, or vendor protocols)joint_trajectory_controllerexecutes planned paths- MoveIt 2 handles planning and IK via a plugin such as KDL, TRAC-IK, or an analytic solver (IKFast)
Minimal URDF Joint Definition (SCARA Example)
<!-- Revolute shoulder joint of a SCARA arm -->
<joint name="joint1" type="revolute">
<parent link="base_link"/>
<child link="link1"/>
<origin xyz="0 0 0.2" rpy="0 0 0"/>
<axis xyz="0 0 1"/> <!-- rotation about vertical axis -->
<limit lower="-2.35" upper="2.35" <!-- radians (~±135 deg) -->
effort="120" velocity="6.28"/> <!-- N·m and rad/s -->
</joint>
<!-- Prismatic Z-axis -->
<joint name="joint3" type="prismatic">
<parent link="link2"/>
<child link="link3"/>
<origin xyz="0.3 0 0" rpy="0 0 0"/>
<axis xyz="0 0 -1"/>
<limit lower="0.0" upper="0.15" effort="200" velocity="1.0"/> <!-- meters -->
</joint>
Controller Configuration
# controllers.yaml
controller_manager:
ros__parameters:
update_rate: 1000 # Hz, control loop rate
joint_trajectory_controller:
type: joint_trajectory_controller/JointTrajectoryController
joint_state_broadcaster:
type: joint_state_broadcaster/JointStateBroadcaster
joint_trajectory_controller:
ros__parameters:
joints: [joint1, joint2, joint3, joint4]
command_interfaces: [position]
state_interfaces: [position, velocity]
constraints:
goal_time: 0.5 # seconds allowed to settle
joint1: {trajectory: 0.05, goal: 0.01} # tolerances in rad
Python Node: Sending a Trajectory Goal
import rclpy
from rclpy.node import Node
from trajectory_msgs.msg import JointTrajectory, JointTrajectoryPoint
from builtin_interfaces.msg import Duration
class PickPlaceNode(Node):
def __init__(self):
super().__init__('pick_place_node')
# Publish directly to the controller's command topic
self.pub = self.create_publisher(
JointTrajectory,
'/joint_trajectory_controller/joint_trajectory', 10)
self.timer = self.create_timer(2.0, self.send_goal)
def send_goal(self):
msg = JointTrajectory()
msg.joint_names = ['joint1', 'joint2', 'joint3', 'joint4']
pt = JointTrajectoryPoint()
pt.positions = [0.5, -0.8, 0.05, 0.0] # rad, rad, m, rad
pt.velocities = [0.0, 0.0, 0.0, 0.0] # stop at the goal
pt.time_from_start = Duration(sec=1, nanosec=0) # reach within 1 s
msg.points.append(pt)
self.pub.publish(msg)
def main():
rclpy.init()
rclpy.spin(PickPlaceNode())
if __name__ == '__main__':
main()
Control Loop Design
Industrial servo drives run cascaded loops:
Position loop (P) ~ 500 Hz - 1 kHz -> velocity command
Velocity loop (PI) ~ 2 - 8 kHz -> torque command
Current loop (PI) ~ 16 - 32 kHz -> PWM voltage
The PID law for any loop:
u(t) = Kp·e(t) + Ki·∫e(τ)dτ + Kd·de(t)/dt
Add feedforward to cut tracking error on fast moves:
τ_cmd = M(q)·q̈_d + C(q, q̇)·q̇_d + G(q) + Kp·e + Kd·ė
where M is the inertia matrix, C the Coriolis/centrifugal term, and G gravity. This computed-torque form matters most for articulated arms, where inertia changes with pose. Delta and SCARA robots benefit most from acceleration feedforward, since they run near their torque limits.
Tuning Order
- Tune the current loop (usually factory-set).
- Tune the velocity loop
Kpuntil the step response shows ~10-20% overshoot, then addKi. - Tune the position loop
Kplast, keeping it below one-fifth of the velocity-loop bandwidth. - Add notch filters at structural resonances (often 20-80 Hz on long arms).
Real-World Workflow: Selecting a Robot for a Pick-and-Place Cell
Scenario: Sort 12 g electronic components from a moving conveyor into trays at 120 picks per minute.
- Compute the cycle budget: 120 picks/min → 0.5 s per pick, including motion, settle, and gripper actuation.
- Filter by payload: 12 g part plus ~150 g gripper → well under any category’s limit.
- Filter by speed: a 6-axis arm struggles at 0.5 s; SCARA and Delta both qualify.
- Check the workspace: conveyor width 400 mm, planar sort. A Delta with vision tracking fits an overhead mount; a SCARA fits if parts are already oriented.
- Check the orientation need: parts arrive randomly rotated. Both offer 1 yaw axis, which suffices.
- Decide: choose the Delta for conveyor tracking at 120+ ppm, or a SCARA if the cell needs a Z-axis insertion step.
- Validate in simulation: import the URDF into Gazebo, run the cycle, and check peak joint torques against the motor’s continuous rating.
Selection Decision Table
| If you need… | Choose | Reason |
|---|---|---|
| Welding or painting around obstacles | Articulated | Full orientation control |
| Fast planar assembly or insertion | SCARA | High speed, Z stiffness |
| 150+ picks/min on light parts | Delta | Lowest moving mass |
| Large workspace or heavy loads | Gantry | Scalable, rigid |
| Lowest programming complexity | Gantry | Direct axis mapping |
| Mobile manipulation (mounted on AMR) | Articulated | Compact, flexible reach |
Frequently Asked Questions
What is the difference between a SCARA and a Delta robot?
A SCARA is a serial robot with two rotary joints and a linear Z-axis, suited to planar assembly with payloads up to about 20 kg. A Delta is a parallel robot with three base-mounted arms, built for the highest pick rates on loads under about 8 kg.
Which industrial robot type is the most accurate?
Gantry robots with ball-screw or linear-motor drives reach the best positioning accuracy (down to ±0.001 mm with linear motors). SCARA robots follow, with typical repeatability of ±0.005-0.02 mm. Articulated arms are usually ±0.02-0.1 mm.
Why do articulated robots have multiple inverse kinematics solutions?
Because joints can reach the same pose in different configurations (elbow up or down, shoulder left or right, wrist flipped). A 6-axis arm with a spherical wrist has up to 8 solutions. Planners choose the one nearest the current joint state.
Can I control an industrial robot with ROS2?
Yes. Use ros2_control with a hardware interface for your drive protocol, joint_trajectory_controller for motion execution, and MoveIt 2 for planning. Many vendors (Universal Robots, FANUC, ABB, KUKA) publish ROS2 drivers.




