compas_cnc.postprocessor.Postprocessor
¤
Postprocessor(tool=None, tool_number=1, feed=200.0, plunge_feed=None, first_cut_feed_factor=None, spindle_speed=12000, coolant='mist', rapid_z=None, rapid_plane=None, home_z=None, material='Aluminum', stock_size=(300.0, 200.0, 20.0), program='2D Contour', precision=4, travel=CARVERA_AIR_TRAVEL, margin=0.0, on_exceed='raise')
Convert tool-path polylines into Carvera Air G-code and write a .nc file.
The Carvera / Carvera Air desktop CNC (Makera) runs a Smoothieware-derived
controller that reads ordinary RS-274 G-code. This post-processor turns the
tool-CENTRE polylines produced by the toolpath_2d_* generators (or any
merged path from :func:toolpath_merge) into the dialect the machine expects:
a % start marker, a commented header (units, tool change, coolant/air,
spindle), a body of G1 linear moves, and a shutdown footer.
The path already encodes its own safe-Z approach, plunge, cut and retract.
Moves at the safe plane -- and, when rapid_plane is set, EVERY move that
stays in the air above it -- are emitted as rapid G0; everything that cuts
goes out as G1 at the programmed feed. Every motion line writes X, Y and Z
explicitly, so each line can be checked on its own against the machine
envelope (no modal-coordinate guessing when reading a program).
Before any G-code is written the path is checked against the machine travel
envelope (:data:CARVERA_AIR_TRAVEL, the factory soft-endstop spans -- the
practical hard limit, since the far end of each axis has no switch). A job
whose bounding-box span overruns the reach raises by default (see
:attr:on_exceed), so an out-of-bounds program is caught here instead of as
a soft-limit halt mid-cut.
The output reproduces this shape::
%
; 3-Axis
; Material: Aluminum
; Stock Size: 300(X) * 200(Y) * 20(Z) mm
; Tool List
; T1-3.175*19mm Flat End
; Path List
; [T1]2D Contour
G90 G21 ; Absolute positioning, units in millimeters
T1 M6 ; Tool change to Tool 1
M7 ; Coolant ON (mist)
S12000 M3 ; Spindle ON clockwise at 12000 RPM
G0 Z50
G1 F200
G1 X-149.8351 Y36.0727
G1 Z20
G1 X-149.8351 Y36.0727 Z-18.8
...
M9 ; Turn off coolant
M05 ; Stop the spindle
G28 ; Goto the machine clearance position
M30 ; End of program
Parameters:
-
tool(:class:`compas_cnc.tools.Tool`, default:None) –The cutting tool. Its name, diameter and height fill the tool-list comment (
T{n}-{diameter}*{height}mm {name}). If omitted a generic description is written. -
tool_number(int, default:1) –Carvera tool-changer slot, used in the
T{n} M6tool change and the header comments. Defaults to1. -
feed(float, default:200.0) –Cutting feed rate (mm/min) set once with
G1 F{feed}. Defaults to200. -
plunge_feed(float, default:None) –Feed rate for a straight Z-DOWN plunge (a move that keeps X/Y and only lowers Z).
None(default) plunges atfeed. -
first_cut_feed_factor(float, default:None) –Scale (in
(0, 1]) applied tofeedfor the FIRST cutting move of EVERY tool-path -- the initial engagement, which bites the deepest as it enters full-thickness stock. Each sub-path in a merged program begins from the safe plane, so the firstG1that leaves the rapid height is slowed tofeed * factor; the rest of that path resumes atfeed.None(default) keeps every cut atfeed.0.5= first cut at half feed. -
spindle_speed(int, default:12000) –Spindle RPM for
S{rpm} M3. Defaults to12000. -
coolant(str | None, default:'mist') –"mist"/"air"->M7,"flood"->M8,None(orFalse) turns coolant off entirely (noM7/M9). Defaults to"mist". -
rapid_z(float, default:None) –World-Z for the opening
G0lift to the travel plane. Defaults to the highest Z in the path (the tool-path's own safe traverse height), so the first cutting move starts from a known clearance height. -
rapid_plane(float, default:None) –World-Z just above the stock top. A straight Z-DOWN plunge from above this plane drops at rapid
G0down to it (pure air travel), then feeds only the remainder into the material -- so a tall safe clearance no longer costs a slow full-depth plunge. Must sit ABOVE all material.None(default) feeds the whole descent as before. -
home_z(float, default:None) –A high absolute Z reached ONLY at the very START (the opening lift) and the very END (a final retract before homing) -- a load/unload or tool-change safety height. The between-pass retracts still use the tool-path's own (lower) safe plane.
None(default) opens and closes at that same safe plane. -
material(str, default:'Aluminum') –Stock material, written into the header comment. Defaults to
"Aluminum". -
stock_size(tuple(float, float, float) | None, default:(300.0, 200.0, 20.0)) –(X, Y, Z)stock dimensions in mm for the header comment.Noneomits the line. Defaults to(300, 200, 20). -
program(str, default:'2D Contour') –Path-list label in the header (
; [T{n}]{program}). Defaults to"2D Contour". -
precision(int, default:4) –Decimal places for coordinates; trailing zeros are stripped. Defaults to
4. -
travel(tuple(float, float, float) | None, default:CARVERA_AIR_TRAVEL) –Per-axis
(X, Y, Z)machine reach in mm the job must fit within. ANoneentry skips that axis;travel=Nonedisables the check entirely. Defaults to :data:CARVERA_AIR_TRAVEL(302, 212, 121). Pass your own jogged values (Makera advise verifying per machine) or :data:CARVERA_AIR_WORKAREAfor the conservative rated area. -
margin(float, default:0.0) –Safety margin in mm subtracted from every
travelaxis before checking, so the job must fit with this much to spare. Defaults to0.0. -
on_exceed(str, default:'raise') –What to do when the path overruns the envelope:
"raise"(default) a :class:ValueError,"warn"a :class:UserWarning, or"ignore".
Attributes:
-
tool, tool_number, feed, spindle_speed, coolant, rapid_z, material,– -
stock_size, program, precision, travel, margin, on_exceed–The configured options above.
body
¤
Motion block printing X, Y and Z on EVERY line, so the height is explicit.
Moves that reach the safe plane (rapid_z) are non-cutting retracts /
repositions and go out as rapid G0; everything below it cuts and goes out
as G1 at feed (or plunge_feed for a straight Z-down plunge).
When rapid_plane is set, EVERY move that stays at or above that plane is
pure air and also goes out as rapid -- this covers the three shapes a path in
air can take:
- a LATERAL link at any safe height (e.g. a merged sub-path whose own safe-Z
sits below the program's
rapid_z) -- both endpoints in air, so the whole straight move is air; - a straight-DOWN plunge from above the plane:
G0down to the plane, then feed only the remainder into the stock -- a tall safe clearance no longer costs a slow full-depth plunge; - a straight-UP retract from below the plane: feed out of the material up to
the plane, then
G0the rest of the lift.
In-material moves are never rapided: a diagonal move with one endpoint below
the plane feeds the whole way. The FIRST cutting move after ANY rapid is
slowed to feed * first_cut_feed_factor when that is set, so each fresh
engagement bites gently before the rest resumes at feed. The feed word is
modal, emitted only when it changes.
check_limits
¤
Travel-envelope violations for toolpaths -- one dict per axis
whose path SPAN exceeds the machine reach.
Returns a list with an entry {"axis", "min", "max", "span", "limit",
"over"} for every axis where the bounding-box span is larger than
:attr:travel (shrunk by :attr:margin); an empty list means the job
fits. The SPAN (not the absolute coordinate) is checked because the work
origin is set on the machine at setup, so what matters at post time is
whether the part fits the reachable travel -- the firmware soft-endstop
span, which on the Carvera Air is the practical hard limit (the far end of
each axis has no switch, only a crash beyond it).
to_gcode
¤
Full .nc program text for one or more tool-paths / polylines.
Each argument may be a toolpath_2d_* object (anything with a .path)
or a raw :class:compas.geometry.Polyline; they are concatenated in order.
The path is checked against the machine travel envelope first (see
:attr:on_exceed).
to_gcode_program
¤
to_gcode_program(sections, tool_change_note='tool change + automatic tool-length touch-off', calibrate=None)
Full .nc for SEVERAL tools run as one Carvera job.
On the Carvera Air every .nc you load needs its own load-probe-cut cycle, so a
two-tool part (e.g. engrave then profile-cut) otherwise means loading, probing and
running twice. This packs the operations into ONE program instead: a single header
and footer, and between them, for EACH section, a T{n} M6 tool change, the
spindle start, that section's motion, and a spindle stop before the next change. So
the machine runs: (probe the STOCK once, set in the Controller) -> change to tool 1,
cut section 1 -> change to tool 2, cut section 2.
Tool-length calibration is part of the Carvera's M6 routine: the change touches
off the newly loaded tool on the setter, and the firmware halts the job if a valid
TLO has not been measured -- so no separate calibration line is needed and every
(including manually fed) tool is re-measured at its M6. calibrate can emit an
EXTRA explicit probe after each M6 for setups that need it, but it is off by
default to avoid a redundant second touch-off.
Parameters:
-
sections(list[tuple]) –Ordered
(tool, tool_number, label, toolpaths)-- one milling operation per physical tool, machined in this order.tool/tool_numberfill that section's tool-change and header comments;labelis its path-list line. -
tool_change_note(str, default:'tool change + automatic tool-length touch-off') –Comment appended to each
T{n} M6line. -
calibrate(str | None, default:None) –Extra tool-length calibration command emitted after each
M6(spindle off) -- e.g."M491"(the Carvera TLO probe).None(default) relies on theM6routine's own touch-off; set it only if your firmware does NOT calibrate in M6. -
Every– -
the– -
single– -
the–
write
¤
Write the .nc program for toolpaths to filepath (.nc added
if missing). Returns the resolved :class:pathlib.Path.
write_program
¤
Write :meth:to_gcode_program for sections to filepath (.nc added if
missing). Returns the resolved :class:pathlib.Path.