A CNC controller looks like one program and is really four, running at four different timescales with strict boundaries between them. Getting those boundaries right is most of the architecture.

The four layers

LayerTimescaleResponsibility
InterpreterMilliseconds, variableParse G-code into canonical commands
Trajectory plannerMilliseconds, ahead of timeVelocity profiles, look-ahead, blending
InterpolatorFixed, 1–10 kHzEmit position setpoints per cycle
Servo controlFixed, 1–20 kHzClose the loop; drive the axes

The architectural rule everything depends on: the bottom two layers are hard real-time and must never wait for the top two. They communicate through a lock-free ring buffer. If the interpreter stalls on a slow file read, the machine keeps moving smoothly on buffered trajectory — it does not stutter.

Layer 1 — Interpretation

The interpreter turns text into intent. Its job is more involved than parsing suggests:

  • Modal state — G-code is stateful. G1 persists until changed; units, plane, and coordinate system all carry forward.
  • Canned cycles — expanding a single drilling cycle into the underlying motion sequence.
  • Cutter compensation — offsetting the path by tool radius, which requires looking ahead to handle corners.
  • Coordinate systems — work offsets, tool length offsets, rotations, and their composition order.
  • Macro programming — variables, arithmetic, conditionals and loops in the dialects that support them.
  • Subprograms — call and return with parameter passing.

Its output should be a clean, dialect-free command stream. That boundary is what lets you support a new controller dialect without touching motion code.

Layer 2 — Trajectory planning

This is where motion quality is decided. The planner converts geometric moves into a time-parameterised velocity profile respecting the machine's physical limits.

  1. Compute segment geometry — length, direction, curvature.
  2. Determine junction velocities — how fast the machine can pass through each corner without exceeding acceleration limits.
  3. Look ahead across many segments so deceleration begins early enough for a distant slow corner.
  4. Apply jerk limiting — S-curve profiles so acceleration changes smoothly rather than instantaneously.
  5. Blend corners within tolerance, so the machine does not stop at every segment junction.

Surface finish is decided here, not in the servo loop. A perfectly tuned control loop following a badly planned trajectory still produces chatter and dwell marks.

Layer 3 — Interpolation

At a fixed rate, the interpolator answers one question: where should every axis be, right now? It walks the planned profile, computes the point along the current segment, and applies inverse kinematics to convert Cartesian position into axis positions.

For a simple 3-axis mill that transform is trivial. For 5-axis, gantry, delta or SCARA machines it is real work, and it is where machine-specific behaviour lives — including singularity handling and soft-limit enforcement.

Layer 4 — Servo control

Per axis, every cycle: read encoder feedback, compare against commanded position, run the control law, output a command.

  • PID with feedforward — velocity and acceleration feedforward dramatically reduce following error compared with feedback alone.
  • Following-error monitoring — if actual position drifts too far from commanded, something is wrong and the machine must stop safely.
  • Output stage — EtherCAT, CANopen, analogue velocity, or step/direction.
  • Watchdog — if the loop stops running, drives must be disabled rather than left commanded.

The parts that surround it

Beyond the four layers, a usable controller needs:

  • IO and PLC logic — spindle, coolant, tool changer, door interlocks, running in the real-time domain.
  • HMI — jogging, MDI, tool tables, offsets, DRO, all in the non-real-time domain.
  • State management — homing, referencing, feed hold, resume, and correct recovery from E-stop.
  • Safety chain — E-stop, limits and interlocks, architected to work alongside certified safety hardware rather than replacing it.

The state machine is underestimated more than the maths. Feed hold during a canned cycle, E-stop mid tool-change, resume after power loss — these paths are where controllers have their worst bugs, because they are hard to test and easy to leave until late. Design them early.

Build, extend, or buy

ApproachSuitsTrade-off
Commercial controllerStandard machinesPer-unit cost; limited extension
LinuxCNC componentsUnusual kinematics, cost-sensitiveYou own integration and support
Custom stackProducts you ship; specific timingLargest investment; full control

Designing a control system or modernising a machine? Tell us the kinematics and drives. See our CNC controller service and real-time motion control fundamentals.

Frequently asked questions

Because they run on completely different timescales. Parsing G-code is variable-latency work that must never block the control loop. Separating them with a buffer lets the interpreter run ahead at whatever speed it can while the real-time side consumes trajectory points at a fixed rate.
An intermediate representation between parsed G-code and motion — commands like STRAIGHT_FEED, ARC_FEED, SET_SPINDLE_SPEED. It decouples dialect handling from motion generation, so supporting a new G-code variant means changing the interpreter, not the planner.
Enough to look ahead across the deceleration distance at maximum feed. On finely tessellated surface programs with very short segments, that can mean hundreds or thousands of blocks. Too little buffer causes the machine to slow unnecessarily at every corner.