Help Getting Plasma Cutter to Turn off Between Faces

Hello, using AutoDesk Fusion 360 to make design for plasma cutter.

When the post processor finishes a face/shape it continues cutting while making its’ way to the starting position of the next shape.

I can fix this by manually editing the GCode, but this would be tedious when I start doing designs that require many cuts.

 

How can I edit the post processor to properly make the GCode.

 

/**
Copyright © 2015-2016 by Autodesk, Inc.
All rights reserved.

Jet template post processor configuration. This post is intended to show
the capabilities for use with waterjet, laser, and plasma cutters. It only
serves as a template for customization for an actual CNC.

Revision: 41096 dedfcdb5a3d9f4565c4f582d694b822c817b986a
Date: 2016-06-26 13:51:08

FORKID {51C1E5C7-D09E-458F-AC35-4A2CE1E0AE32}
*/

description = “MPCNC Laser Plasma Cutter”;
vendor = “Autodesk”;
vendorUrl = “http://www.autodesk.com”;
legal = “Copyright © 2015-2016 by Autodesk, Inc.”;
certificationLevel = 2;
minimumRevision = 39000;

longDescription = “Laser/Plasma post processor for MPCNC machine. Laser/Plasma controlled by M106 Sxxx and M107 gcodes with Marlin firmware.”;

capabilities = CAPABILITY_JET;
extension = “gcode”;
setCodePage(“ascii”);

tolerance = spatial(0.002, MM);

minimumChordLength = spatial(0.01, MM);
minimumCircularRadius = spatial(0.01, MM);
maximumCircularRadius = spatial(1000, MM);
minimumCircularSweep = toRad(0.01);
maximumCircularSweep = toRad(180);
allowHelicalMoves = false;
allowedCircularPlanes = undefined; // allow any circular motion

// Default alternative feedrate as workaround for Fusion 360 bug
// https://forums.autodesk.com/t5/computer-aided-machining-cam/post-processor-feed-rate-problem/td-p/6704717
// Feedrate bug
altfeed = 1000;

// hardcoded properties
hproperties = {
writeMachine: true, // write machine
showSequenceNumbers: false, // show sequence numbers
sequenceNumberStart: 10, // first sequence number
sequenceNumberIncrement: 5, // increment for sequence numbers
allowHeadSwitches: false, // output code to allow heads to be manually switched for piercing and cutting
useRetracts: false, // output retracts - otherwise only output part contours for importing in third-party jet application
separateWordsWithSpace: true // specifies that the words should be separated with a white space
};

// user-defined properties
properties = {
TURN_ON: “M106 S255”, // GCode command to turn on the laser/plasma
TURN_OFF: “M107” // Gcode command to turn off the laser/plasma
};

var gFormat = createFormat({prefix:“G”, decimals:0});
var mFormat = createFormat({prefix:“M”, decimals:0});

var xyzFormat = createFormat({decimals:(unit == MM ? 3 : 4)});
var feedFormat = createFormat({decimals:(unit == MM ? 1 : 2)});
var secFormat = createFormat({decimals:3, forceDecimal:true}); // seconds - range 0.001-1000

var xOutput = createVariable({prefix:“X”}, xyzFormat);
var yOutput = createVariable({prefix:“Y”}, xyzFormat);
var feedOutput = createVariable({prefix:“F”}, feedFormat);

// circular output
var iOutput = createReferenceVariable({prefix:“I”}, xyzFormat);
var jOutput = createReferenceVariable({prefix:“J”}, xyzFormat);

var gMotionModal = createModal({force:true}, gFormat); // modal group 1 // G0-G3, …
var gAbsIncModal = createModal({}, gFormat); // modal group 3 // G90-91
var gUnitModal = createModal({}, gFormat); // modal group 6 // G20-21

var WARNING_WORK_OFFSET = 0;

// collected state
var sequenceNumber;
var currentWorkOffset;
var split = false;

/**
Writes the specified block.
*/
function writeBlock() {
if (hproperties.showSequenceNumbers) {
writeWords2(“N” + sequenceNumber, arguments);
sequenceNumber += hproperties.sequenceNumberIncrement;
} else {
writeWords(arguments);
}
}

function formatComment(text) {
return “(” + String(text).replace(/[()]/g, “”) + “)”;
}

/**
Output a comment.
*/
function writeComment(text) {
writeln(formatComment(text));
}

function onOpen() {

if (!hproperties.separateWordsWithSpace) {
setWordSeparator("");
}

sequenceNumber = hproperties.sequenceNumberStart;

if (programName) {
writeComment(programName);
}
if (programComment) {
writeComment(programComment);
}

// dump machine configuration
var vendor = machineConfiguration.getVendor();
var model = machineConfiguration.getModel();
var description = machineConfiguration.getDescription();

if (hproperties.writeMachine && (vendor || model || description)) {
writeComment(localize(“Machine”));
if (vendor) {
writeComment(" " + localize(“vendor”) + “: " + vendor);
}
if (model) {
writeComment(” " + localize(“model”) + “: " + model);
}
if (description) {
writeComment(” " + localize(“description”) + ": " + description);
}
}

if (hasGlobalParameter(“material”)) {
writeComment("MATERIAL = " + getGlobalParameter(“material”));
}

if (hasGlobalParameter(“material-hardness”)) {
writeComment("MATERIAL HARDNESS = " + getGlobalParameter(“material-hardness”));
}

{ // stock - workpiece
var workpiece = getWorkpiece();
var delta = Vector.diff(workpiece.upper, workpiece.lower);
if (delta.isNonZero()) {
writeComment("THICKNESS = " + xyzFormat.format(workpiece.upper.z - workpiece.lower.z));
}
}

// absolute coordinates and feed per min
writeBlock(gAbsIncModal.format(90));

switch (unit) {
case IN:
writeBlock(gUnitModal.format(20));
break;
case MM:
writeBlock(gUnitModal.format(21));
break;
}
}

function onComment(message) {
writeComment(message);
}

/** Force output of X, Y, and Z. */
function forceXYZ() {
xOutput.reset();
yOutput.reset();
}

/** Force output of X, Y, Z, A, B, C, and F on next output. */
function forceAny() {
forceXYZ();
feedOutput.reset();
}

function onSection() {
var insertToolCall = isFirstSection() ||
currentSection.getForceToolChange && currentSection.getForceToolChange() ||
(tool.number != getPreviousSection().getTool().number);

var retracted = false; // specifies that the tool has been retracted to the safe plane
var newWorkOffset = isFirstSection() ||
(getPreviousSection().workOffset != currentSection.workOffset); // work offset changes
var newWorkPlane = isFirstSection() ||
!isSameDirection(getPreviousSection().getGlobalFinalToolAxis(), currentSection.getGlobalInitialToolAxis());

writeln("");

if (hasParameter(“operation-comment”)) {
var comment = getParameter(“operation-comment”);
if (comment) {
writeComment(comment);
}
}

if (insertToolCall) {
retracted = true;
onCommand(COMMAND_COOLANT_OFF);

switch (tool.type) {
case TOOL_WATER_JET:
writeComment(“Waterjet cutting.”);
break;
case TOOL_LASER_CUTTER:
writeComment(“Laser cutting”);
break;
case TOOL_PLASMA_CUTTER:
writeComment(“Plasma cutting”);
break;
/*
case TOOL_MARKER:
writeComment(“Marker”);
break;
*/
default:
error(localize(“The CNC does not support the required tool.”));
return;
}
writeln("");

writeComment(“tool.jetDiameter = " + xyzFormat.format(tool.jetDiameter));
writeComment(“tool.jetDistance = " + xyzFormat.format(tool.jetDistance));
writeln(””);

switch (currentSection.jetMode) {
case JET_MODE_THROUGH:
writeComment(“THROUGH CUTTING”);
break;
case JET_MODE_ETCHING:
writeComment(“ETCH CUTTING”);
break;
case JET_MODE_VAPORIZE:
writeComment(“VAPORIZE CUTTING”);
break;
default:
error(localize(“Unsupported cutting mode.”));
return;
}
writeComment("QUALITY = " + currentSection.quality);

if (tool.comment) {
writeComment(tool.comment);
}
writeln("");
}

forceXYZ();

{ // pure 3D
var remaining = currentSection.workPlane;
if (!isSameDirection(remaining.forward, new Vector(0, 0, 1))) {
error(localize(“Tool orientation is not supported.”));
return;
}
setRotation(remaining);
}

forceAny();

split = false;
if (hproperties.useRetracts) {

var initialPosition = getFramePosition(currentSection.getInitialPosition());

if (insertToolCall || retracted) {
gMotionModal.reset();

if (!machineConfiguration.isHeadConfiguration()) {
writeBlock(
gAbsIncModal.format(90),
gMotionModal.format(0), xOutput.format(initialPosition.x), yOutput.format(initialPosition.y)
);
} else {
writeBlock(
gAbsIncModal.format(90),
gMotionModal.format(0),
xOutput.format(initialPosition.x),
yOutput.format(initialPosition.y)
);
}
} else {
writeBlock(
gAbsIncModal.format(90),
gMotionModal.format(0),
xOutput.format(initialPosition.x),
yOutput.format(initialPosition.y)
);
}
} else {
split = true;
}
}

function onDwell(seconds) {
if (seconds > 99999.999) {
warning(localize(“Dwelling time is out of range.”));
}
seconds = clamp(0.001, seconds, 99999.999);
writeBlock(gFormat.format(4), “X” + secFormat.format(seconds));
}

function onCycle() {
onError(“Drilling is not supported by CNC.”);
}

var pendingRadiusCompensation = -1;

function onRadiusCompensation() {
pendingRadiusCompensation = radiusCompensation;
}

var shapeArea = 0;
var shapePerimeter = 0;
var shapeSide = “inner”;
var cuttingSequence = “”;

function onParameter(name, value) {

// Feedrate bug
if (name == “operation:tool_feedCutting”) {
altfeed = value;
}

if ((name == “action”) && (value == “pierce”)) {
writeComment(“RUN POINT-PIERCE COMMAND HERE”);
} else if (name == “shapeArea”) {
shapeArea = value;
writeComment(“SHAPE AREA = " + xyzFormat.format(shapeArea));
} else if (name == “shapePerimeter”) {
shapePerimeter = value;
writeComment(“SHAPE PERIMETER = " + xyzFormat.format(shapePerimeter));
} else if (name == “shapeSide”) {
shapeSide = value;
writeComment(“SHAPE SIDE = " + value);
} else if (name == “beginSequence”) {
if (value == “piercing”) {
if (cuttingSequence != “piercing”) {
if (hproperties.allowHeadSwitches) {
writeln(””);
writeComment(“Switch to piercing head before continuing”);
onCommand(COMMAND_STOP);
writeln(”");
}
}
} else if (value == “cutting”) {
if (cuttingSequence == “piercing”) {
if (hproperties.allowHeadSwitches) {
writeln("");
writeComment(“Switch to cutting head before continuing”);
onCommand(COMMAND_STOP);
writeln("");
}
}
}
cuttingSequence = value;
}
}

var deviceOn = false;

function setDeviceMode(enable) {
if (enable != deviceOn) {
deviceOn = enable;
if (enable) {
writeComment(“LASER/PLASMA ON”);
writeBlock(properties.TURN_ON);
} else {
writeComment(“LASER/PLASMA OFF”);
writeBlock(properties.TURN_OFF);
}
}
}

function onPower(power) {
setDeviceMode(power);
}

function onRapid(_x, _y, _z) {

if (!hproperties.useRetracts && ((movement == MOVEMENT_RAPID) || (movement == MOVEMENT_HIGH_FEED))) {
doSplit();
return;
}

if (split) {
split = false;
var start = getCurrentPosition();
onRapid(start.x, start.y, start.z);
}

var x = xOutput.format(_x);
var y = yOutput.format(_y);
if (x || y) {
if (pendingRadiusCompensation >= 0) {
error(localize(“Radius compensation mode cannot be changed at rapid traversal.”));
return;
}
writeBlock(gMotionModal.format(0), x, y);
feedOutput.reset();
}
}

function onLinear(_x, _y, _z, feed) {

if (!hproperties.useRetracts && ((movement == MOVEMENT_RAPID) || (movement == MOVEMENT_HIGH_FEED))) {
doSplit();
return;
}

if (split) {
resumeFromSplit(feed);
}

// at least one axis is required
if (pendingRadiusCompensation >= 0) {
// ensure that we end at desired position when compensation is turned off
xOutput.reset();
yOutput.reset();
}
var x = xOutput.format(_x);
var y = yOutput.format(_y);

// Feedrate bug
if(feed != 0) {
var f = feedOutput.format(feed);
} else {
var f = feedOutput.format(altfeed);
}

if (x || y) {
if (pendingRadiusCompensation >= 0) {
pendingRadiusCompensation = -1;
switch (radiusCompensation) {
case RADIUS_COMPENSATION_LEFT:
writeBlock(gFormat.format(41));
writeBlock(gMotionModal.format(1), x, y, f);
break;
case RADIUS_COMPENSATION_RIGHT:
writeBlock(gFormat.format(42));
writeBlock(gMotionModal.format(1), x, y, f);
break;
default:
writeBlock(gFormat.format(40));
writeBlock(gMotionModal.format(1), x, y, f);
}
} else {
writeBlock(gMotionModal.format(1), x, y, f);
}
} else if (f) {
if (getNextRecord().isMotion()) { // try not to output feed without motion
feedOutput.reset(); // force feed on next line
} else {
writeBlock(gMotionModal.format(1), f);
}
}
}

function onRapid5D(_x, _y, _z, _a, _b, _c) {
error(localize(“The CNC does not support 5-axis simultaneous toolpath.”));
}

function onLinear5D(_x, _y, _z, _a, _b, _c, feed) {
error(localize(“The CNC does not support 5-axis simultaneous toolpath.”));
}

function doSplit() {
if (!split) {
split = true;
gMotionModal.reset();
xOutput.reset();
yOutput.reset();
feedOutput.reset();
}
}

function resumeFromSplit(feed) {
if (split) {
split = false;
var start = getCurrentPosition();
var _pendingRadiusCompensation = pendingRadiusCompensation;
pendingRadiusCompensation = -1;
onLinear(start.x, start.y, start.z, feed);
pendingRadiusCompensation = _pendingRadiusCompensation;
}
}

function onCircular(clockwise, cx, cy, cz, x, y, z, feed) {

if (!hproperties.useRetracts && ((movement == MOVEMENT_RAPID) || (movement == MOVEMENT_HIGH_FEED))) {
doSplit();
return;
}

// one of X/Y and I/J are required and likewise

if (pendingRadiusCompensation >= 0) {
error(localize(“Radius compensation cannot be activated/deactivated for a circular move.”));
return;
}

if (split) {
resumeFromSplit(feed);
}

var start = getCurrentPosition();
if (isFullCircle()) {
if (isHelical()) {
linearize(tolerance);
return;
}
switch (getCircularPlane()) {
case PLANE_XY:

// Feedrate bug
if(feed != 0) {
var f = feedOutput.format(feed);
} else {
var f = feedOutput.format(altfeed);
}

writeBlock(gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), f);
break;
default:
linearize(tolerance);
}
} else {
switch (getCircularPlane()) {
case PLANE_XY:

// Feedrate bug
if(feed != 0) {
var f = feedOutput.format(feed);
} else {
var f = feedOutput.format(altfeed);
}

writeBlock(gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), f);
break;
default:
linearize(tolerance);
}
}
}

var mapCommand = {
COMMAND_STOP:0,
COMMAND_OPTIONAL_STOP:1,
COMMAND_END:2
};

function onCommand(command) {
switch (command) {
case COMMAND_POWER_ON:
return;
case COMMAND_POWER_OFF:
return;
case COMMAND_COOLANT_ON:
return;
case COMMAND_COOLANT_OFF:
return;
case COMMAND_LOCK_MULTI_AXIS:
return;
case COMMAND_UNLOCK_MULTI_AXIS:
return;
case COMMAND_BREAK_CONTROL:
return;
case COMMAND_TOOL_MEASURE:
return;
}

var stringId = getCommandStringId(command);
var mcode = mapCommand[stringId];
if (mcode != undefined) {
writeBlock(mFormat.format(mcode));
} else {
onUnsupportedCommand(command);
}
}

function onSectionEnd() {
setDeviceMode(false);
forceAny();
}

function onClose() {
writeln("");

onCommand(COMMAND_COOLANT_OFF);

onImpliedCommand(COMMAND_END);
writeBlock(mFormat.format(30)); // stop program
}

 

Hmm, shouldn’t the torch stop when you raise the z axis far enough? You may need to increase the safe height if you’re not using a THC.

Which M code do you have set to stop the torch?