DryRun

User guide

6. G-code support

The dialect is controller.dialect in machine.json (section 4.2): DDCS V4.1 (the default), GRBL 1.1 or grblHAL. Section 6.1 is the syntax of each, section 6.2 the DDCS V4.1 code table, section 6.3 the GRBL 1.1 and grblHAL code table. The two families are handled in opposite ways. GRBL is precisely specified by its source, so the simulator rejects what GRBL rejects, with GRBL's error number (section 6.3; it was compared line by line with GRBL 1.1h built as grbl-sim, and the few known differences are listed there); the published page GRBL 1.1 and grblHAL in DryRun summarises it. For DDCS V4.1 the simulator follows the manual, which is short and partly contradictory; docs/research/03-ddcs-v41-dialect.md lists the sources. Where the manual is silent or contradicts itself, the simulator picks the most likely behaviour, executes it and attaches a warning ending in — behaviour on DDCS not confirmed. Unlike the simulator, the real DDCS V4.1 stops at a line it cannot parse ("parsing error prompt"); the simulator skips the line and continues so you see every problem in one pass.

6.1 Words and syntax

DDCS V4.1:

GRBL 1.1 and grblHAL (research §1.3, gnea's protocol.c): everything below is documented GRBL syntax, so it gives no note unless one is named.

6.2 Code table (DDCS V4.1)

"Executed" = simulated. "Ignored" = the code is dropped with a warning and the rest of the line runs. "Line skipped" = the whole line is not executed (warning). "Error" = the whole line is not executed (red).

Code Handling Behaviour in the simulator
G0 Executed Rapid move at rapidFeed; straight, or a dog-leg with rapidMode: "independent".
G1 Executed Straight feed move.
G2 / G3 Executed Arc in the active plane, centre by I/J/K (always incremental from the start point) or by R. Full circles with I/J/K. Start and end radius must agree within 0.002 mm, else error arc radius mismatch. A full circle with R is an error. R < 0 (arc over 180°) is executed as the long arc with a "not confirmed" warning. A move of the axis normal to the plane makes a helix, warned once as "not confirmed". An A word in an arc is an error.
G4 Executed Dwell. P in ms (or s with dwellPUnits: "s"). G4 X<seconds> is accepted with a "not confirmed" warning. G4 without P or X, a negative value, or G4 with a motion on the same line are errors.
G17 / G18 / G19 Executed Arc plane XY / ZX / YZ.
G20 / G21 Executed Inch / mm input. Inch values of X, Y, Z, I, J, K, R, Q and F are converted to mm; A stays in degrees.
G28 Executed, "not confirmed" Rapid to the given point (in the current G90/G91 mode), then rapid to machine 0 on the named axes only. Without axis words nothing moves. Warnings: the DDCS may use reference point #800–#803 instead of machine 0, and in G90 that the V3.1 manual says G28 works only with G91.
G40 Executed Accepted, no effect (compensation is never active).
G41 / G42 Ignored cutter radius compensation is not simulated; path is uncompensated. The simulated path is the programmed path, not the compensated one.
G43 H / G49 Executed Tool length offset on (length of tool H) / off. Errors: G43 without H, H outside 0–16, H of a tool not in the table. Warnings: G43 H<n> while T<m> is active, and tool changed to T<n> but length offset H<m> is still active on the first move after such an M6.
G44 Ignored Documented as not working on the DDCS.
G53 Executed Move in machine coordinates on this line only. Uses G0 unless G1 is the active motion mode, in which case it is a feed move (DDCS behaviour not documented) and the warning G53 with G1 active: the move runs at feed rate says so; with G2/G3 active it is an error. A G53 move is positioning: it never counts as a cut for "From program extents" or the tool defaults.
G54–G59 Executed Select a work offset from setup.json.
G73 / G81 / G82 / G83 Executed, "not confirmed" Canned cycles, Fanuc semantics (absolute R and Z in G90): rapid to X/Y, rapid to R, then G81 feed to Z; G82 the same plus a dwell P (ms, or s with dwellPUnits: "s"); G83 peck by Q with full retract to R and rapid re-approach to 1 mm above the previous depth; G73 peck by Q with a 1 mm retract. Retract to the initial Z (G98) or to R (G99). Later lines with X/Y (or R) drill more holes until G80 or another motion code. K or L = repeat count. Warnings: Z/R semantics differ between DDCS manuals; G82 P units; K in G73/G83 may be a clearance on the DDCS; L. Errors: missing R or Z, R below Z, Q ≤ 0 for G73/G83, negative G82 P, a repeat count that is not a whole number ≥ 1. In G91 or outside G17 the line is skipped.
G80 Executed Cancels the canned cycle mode.
G90 / G91 Executed Absolute / incremental axis words (I/J/K are always incremental).
G90.1 / G91.1 Ignored Arc centre mode is not simulated; positions after this line may differ.
G92 Executed Shifts the work coordinates so the current position reads the given values; the shift is added to whichever G54–G59 is active afterwards. There is no G92.1.
G93 Ignored Inverse-time feed is not documented for V4.1; the move is timed as G94.
G94 Executed Accepted (feed per minute is the only mode).
G98 / G99 Executed Canned cycle retract plane.
G15 / G16, G68 / G69 Ignored Polar coordinates and rotation are not simulated; positions after this line may differ.
G12 G13 G30 G31 G74 G76 G84–G89 G102 G103 G110–G112 G128 G153 Line skipped not simulated; line skipped, positions after this line may differ from the controller.
Any other G code (G10, G5, G59.1, …) Error <code>: unknown code on DDCS V4.1; line skipped.
M0 Executed Accepted; the simulation does not pause.
M2 Executed Program end, with a warning (not documented for the DDCS).
M3 / M4 / M5, M8 / M9, M10 / M11 Executed Accepted, no effect. Spindle and coolant state are not tracked.
M6 Executed Tool change to the last T word: instant, at the current position, no motion (the DDCS pauses for a manual change; #905 moves are not simulated). Errors: M6 without T, a tool not in the table (the previous tool stays in), T outside 0–16. M6 T0 empties the spindle.
M30 Executed Program end. A program without M30 (or M2/M47/M99 in the main program) gets the warning program has no M30.
M47 Executed Treated as program end, with a warning (it repeats forever on the controller).
M98 P L / M99 Executed, "not confirmed" Call subprogram O<P> (a line starting with O<n> in the same file) L times, nesting up to 8. Warning: needs #122 = Enable on the controller. M99 returns; M99 P/L are ignored with a warning; M99 in the main program ends it with a warning. Errors: missing P, unknown O number, bad L, duplicate O label.
M1, M7, M29, M101, M102, M110 Ignored With a warning each.
M105–M108 Line skipped Homing is not simulated.
Any other M code Ignored custom M code (slib-m.nc on the controller) is not simulated. On your controller such a code may move axes.

Other behaviour:

6.3 GRBL 1.1 and grblHAL

GRBL is precisely specified, so instead of warnings the simulator rejects what GRBL rejects, with GRBL's error number: a red entry GRBL rejects G81 (error:20, unsupported command) (on grblHAL grblHAL rejects …), the line not executed. A block is checked completely before it runs, as GRBL does, so a rejected line changes no modal state. Sources: docs/research/05-grbl-dialects.md §1 and §2 (gnea/grbl 1.1h gcode.c, grblHAL core build 20261004); the published page GRBL 1.1 and grblHAL in DryRun has GRBL's full error table.

The DO NOT RUN rule. GRBL itself only discards the bad line and answers error:N, but Carbide Motion, gSender, UGS and CNCjs stop the job on that reply: on the machine the job ends part-way, with the spindle on and the tool possibly in the material. So any rejected line makes the verdict DO NOT RUN (section 2), with the count and the first one: 4 rejected lines — GRBL rejects line 2 (error:20); the sender stops the job there, and the Check tag Problems, even when nothing collides. The first rejected line of a program adds — the sender stops the job here; the simulation goes on as if you continued; the simulation does continue, so one pass shows every problem. Rejected lines are tagged Not executed and do not count in the INCOMPLETE banner's N lines were not executed (section 7.11). Whether your sender really stops is not confirmed (section 7.12, G1).

Code table. "Executed" = simulated. "No effect" = accepted and executed without motion or state the check uses. "Line skipped" = a warning, the line not executed. "Error n" = rejected with GRBL's error n (the hint, if any, is part of the message).

Code GRBL 1.1 grblHAL Behaviour in the simulator
G0, G1 Executed Executed G0 is one straight move at rapidFeed. G1 at the program's F; a G1/G2/G3 before any F (or after F0) is error 22.
G2, G3 Executed Executed Arcs (below): IJK always incremental, R, helical, R < 0.
G4 Executed Executed Dwell; P in seconds. Without P: error 28. Axis words on the line move after the dwell in the active motion mode (G4 P1 X1).
G5, G5.1 Error 20 Line skipped Splines are not simulated.
G10 L2, G10 L20 Executed Executed Change the run's copy of a work offset (below). Other L: error 20; on grblHAL with a tool table L1/L10/L11 are accepted with a note.
G17, G18, G19, G20, G21, G90, G91, G94 Executed Executed Plane, units, distance, feed per minute.
G28, G30, G28.1, G30.1 Executed Executed The stored positions controller.g28 / g30 (below).
G38.2–G38.5 Line skipped Line skipped probing not simulated; line skipped, positions after this line may differ from the controller.
G40, G61, G91.1 No effect No effect The only modes GRBL has; accepted for program headers.
G41, G42 Error 20 Error 20 Cutter compensation (off in grblHAL's default build).
G43 H Error 20, GRBL has no tool table — a Fanuc/generic post; use a GRBL post With toolTable: true executed (tool H's length); without, error 20 this grblHAL has no tool table (N_TOOLS = 0) Section 4.2, toolTable.
G43.1, G49 Executed (G43.1 with exactly Z, else error 37; G49 with a decimal, G49.1, is G49) Executed (G43.1 on any axis; X/Y give length offset on X/Y not simulated) Dynamic tool length offset, added to the touched-off length; G49 cancels it.
G50, G51 Error 20 Line skipped Scaling is not simulated.
G53 Executed Executed With G0 or G1 active (G1: at the feed rate); under G2/G3/G80 error 30.
G54–G59 Executed Executed Work offsets from setup.json.
G59.1–G59.3 Error 23 Line skipped grblHAL has them; setup.json does not.
G61.1, G64, G90.1 Error 20 (G64: remove the G64 line) Error 20
G73, G81, G82, G83 Error 20, turn off canned cycles in the post or use the GRBL post Executed grblHAL's canned cycles (below).
G84 Error 20 Error 20, G84 needs a spindle that reports "at speed"
G85, G86, G89 Error 20 Executed
G87, G88 Error 20 Error 20
G80 Executed Executed Cancels the motion mode; axis words while it is active are error 31 (grblHAL allows them on G10/G28/G30/G92). On grblHAL also back to G98.
G92, G92.1 Executed Executed G92 needs axis words (else error 26); G92.1 clears it. M2/M30 do not clear it.
G93 Executed Executed Inverse time: F is 1/minutes for its own line (G93 G1 X10 F2 takes half a minute, never inches). A G1/G2/G3 without F on its line is error 22; back in G94 the feed is undefined until a new F (error 22). grblHAL: a canned cycle started in G93 is error 3.
G98, G99 Error 20 Executed Canned-cycle retract.
G7, G8, G33, G76, G95–G97 Error 20 Error 20 Lathe codes.
M0, M1, M2, M30 Executed Executed M0 does not pause the simulation; M1 no effect; M2 and M30 end the run without a note.
M3, M4, M5, M8, M9 No effect No effect Spindle and coolant are not tracked.
M6 Tool change Tool change As controller.toolChange says (section 4.2; touch-off by default, with a note). With "controller": error 20 on GRBL 1.1, a plain change on grblHAL.
M7 Error 20 No effect Stock GRBL 1.1 compiles M7 out.
M61 Q Error 20 Executed Sets the tool in the spindle without a change; without Q error 28.
M62–M68 Error 20 No effect
M70–M73 Error 20 Ignored, modal state save/restore is not simulated
M98, M99 and any other G or M code Error 20 Error 20 GRBL has no subprograms; an unknown Gxx.x of an integer code (G1.5) or any Mxx.x is error 23.
#, [ Error 1 (#1=5) or 2 (G0 X#1) Line skipped, macros and # variables are not simulated; line skipped
O words Error 20 Line skipped, as #

Other rejections, by number: error:21 two codes of one modal group (G0 G80, M8 M9, M3 M5, G4 G53, G90 G91); 24 two codes that use axis words (G0 G1 X1, G28 G1 X1, G92 G0 X1; GRBL checks this before the modal groups, and on GRBL 1.1 before it refuses a G43, G38.x or Gxx.x that follows a motion code on the line: G0 G43 Z15 H1 is 24, G43 Z15 H1 alone 20); 25 a letter twice (X1 X2); 4 a negative F, N, P, S or T; 38 T > 255 (grblHAL with a tool table: a T, H or M61 Q that is not a tool in setup.json); 27 N > 10 000 000; 36 unused value words (G0 X1 R2, G1 X1 P1, a lone P5); the motion rules below (26, 29, 30, 32–35, 37); 2 a letter without a number (G1 X); 1 a stray character (G0 X1 ,); 11 a line over 79 characters (section 6.1). grblHAL adds 19 (non-positive value) and 54 (retract position below the hole bottom) for canned-cycle words.

Known differences from GRBL 1.1h (a line-by-line comparison with GRBL 1.1h built as grbl-sim, tools/grbl-oracle/): values over 100 000 mm (GRBL accepts them and drives there; the simulator refuses the line with number out of range: X200000 — GRBL accepts it and drives there; the simulator stops at 100 000 mm); M2/M30 (GRBL goes on with lines the sender still streams; the simulation stops); % and $ lines (a note and a warning, section 6.1).