/** Copyright (C) 2012-2021 by Autodesk, Inc. All rights reserved. Masso Plasma post processor configuration. $Revision: 43693 62109a50de0f7334620074c43cb6dace7a198c28 $ $Date: 2022-03-09 19:26:40 $ FORKID {2053f562-720f-4c63-ac2f-68bf2297762f} */ description = "Masso Plasma"; vendor = "Hind Technology Australia"; vendorUrl = "https://masso.com.au"; legal = "Copyright (C) 2012-2021 by Autodesk, Inc."; certificationLevel = 2; minimumRevision = 45702; highFeedrate = (unit == IN) ? 100 : 2500; longDescription = "Generic post for Masso plasma."; extension = "nc"; setCodePage("ascii"); capabilities = CAPABILITY_JET; tolerance = spatial(0.002, MM); minimumChordLength = spatial(0.25, MM); minimumCircularRadius = spatial(0.01, MM); maximumCircularRadius = spatial(1000, MM); minimumCircularSweep = toRad(0.01); maximumCircularSweep = toRad(180); allowHelicalMoves = false; allowedCircularPlanes = 1 << PLANE_XY; // only XY // user-defined properties properties = { writeMachine: { title : "Write machine", description: "Output the machine settings in the header of the code.", group : 0, type : "boolean", value : true, scope : "post" }, safePositionMethod: { title : "Safe Retracts", description: "Select your desired retract option. 'Clearance Height' retracts to the operation clearance height.", type : "enum", values : [ {title:"G28", id:"G28"}, {title:"G53", id:"G53"}, {title:"Clearance Height", id:"clearanceHeight"} ], value: "clearanceHeight", scope: "post" }, showSequenceNumbers: { title : "Use sequence numbers", description: "Use sequence numbers for each block of outputted code.", group : 1, type : "boolean", value : true, scope : "post" }, sequenceNumberStart: { title : "Start sequence number", description: "The number at which to start the sequence numbers.", group : 1, type : "integer", value : 10, scope : "post" }, sequenceNumberIncrement: { title : "Sequence number increment", description: "The amount by which the sequence number is incremented by in each block.", group : 1, type : "integer", value : 5, scope : "post" }, separateWordsWithSpace: { title : "Separate words with space", description: "Adds spaces between words if 'yes' is selected.", type : "boolean", value : true, scope : "post" }, pierceDelay: { title : "Pierce delay", description: "Specifies the delay to pierce in seconds.", group : 3, type : "number", value : 1, scope : "post" }, probeOffset: { title : "Probe offset", description: "Specifies the offset for G38.2 probing.", group : 4, type : "number", value : 0, scope : "post" }, probe: { title : "Probe", description: "Specifies whether to use probing.", group : 4, type : "boolean", value : false, scope : "post" }, useZAxis: { title : "Use Z axis", description: "Specifies to enable the output for Z coordinates.", type : "boolean", value : false, scope : "post" }, pierceHeight: { title : "Pierce Height", description: "Specifies the pierce height.", group : 3, type : "number", value : 0, scope : "post" }, useG0: { title : "Use G0", description: "Toggle between using G0 or G1 with a highFeedrate for rapid movements.", type : "boolean", value : true, scope : "post" }, useParenthesesForComments: { title : "Use parentheses for comment", description: "Set to true to use parentheses and false to use pound sign for comment.", type : "boolean", value : true, scope : "post" }, minThcFeed: { title : "Minimum THC feed rate", description: "THC will get turned off if the programmed feedrates are below this value.", group : 2, type : "number", value : 0, scope : "post" }, thcFeed: { title : "THC Z axis feed rate", description: "Set feed rate for THC.", group : 2, type : "number", value : 0, scope : "post" } }; // wcs definiton wcsDefinitions = { useZeroOffset: true, wcs : [ {name:"Standard", format:"G", range:[53, 59]} ] }; var permittedCommentChars = " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,=_-"; var gFormat = createFormat({prefix:"G", decimals:0}); var g1Format = createFormat({prefix:"G", decimals:1, forceDecimal:false}); var mFormat = createFormat({prefix:"M", decimals:0}); var xyzFormat = createFormat({decimals:(unit == MM ? 3 : 4), forceDecimal:true}); var zFormat = createFormat({decimals:(unit == MM ? 3 : 4), forceDecimal:true}); var abcFormat = createFormat({decimals:3, forceDecimal:true, scale:DEG}); var secFormat = createFormat({decimals:0, forceDecimal:false, scale:1000}); // seconds - range 0.001-1000 var feedFormat = createFormat({decimals:(unit == MM ? 2 : 3), forceDecimal:true}); var xOutput = createVariable({prefix:"X"}, xyzFormat); var yOutput = createVariable({prefix:"Y"}, xyzFormat); var zOutput = createVariable({prefix:"Z"}, zFormat); var aOutput = createVariable({prefix:"A"}, abcFormat); var bOutput = createVariable({prefix:"B"}, abcFormat); var cOutput = createVariable({prefix:"C"}, abcFormat); var feedOutput = createVariable({prefix:"F"}, feedFormat); // circular output var iOutput = createReferenceVariable({prefix:"I", force:true}, xyzFormat); var jOutput = createReferenceVariable({prefix:"J", force:true}, xyzFormat); var kOutput = createReferenceVariable({prefix:"K", force:true}, xyzFormat); var gMotionModal = createModal({}, gFormat); // modal group 1 // G0-G3, ... var gAbsIncModal = createModal({}, gFormat); // modal group 3 // G90-91 var gUnitModal = createModal({}, gFormat); // modal group 6 // G20-22 var mThcModal = createModal({}, mFormat); // modal M code for THC command // collected state var sequenceNumber; var initialStraightProbe = false; var currentWorkOffset; var retracted = false; /** Writes the specified block. */ function writeBlock() { if (getProperty("showSequenceNumbers")) { writeWords2("N" + sequenceNumber, arguments); sequenceNumber += getProperty("sequenceNumberIncrement"); } else { writeWords(arguments); } } function formatComment(text) { if (getProperty("useParenthesesForComments")) { return "(" + filterText(String(text).toUpperCase(), permittedCommentChars).replace(/[()]/g, "") + ")"; } else { return "# " + filterText(String(text).toUpperCase(), permittedCommentChars).replace(/[#]/g, ""); } } /** Output a comment. */ function writeComment(text) { writeln(formatComment(text)); } function onOpen() { if (getProperty("useZAxis")) { zFormat.setOffset(getProperty("pierceHeight")); zOutput = createVariable({prefix:"Z"}, zFormat); } else { zOutput.disable(); } if (!getProperty("separateWordsWithSpace")) { setWordSeparator(""); } sequenceNumber = getProperty("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 (getProperty("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); } } switch (unit) { case IN: writeBlock(gUnitModal.format(20)); // or use M20 break; case MM: writeBlock(gUnitModal.format(21)); // or use M21 break; } writeBlock(feedOutput.format(1)); writeBlock(gFormat.format(53), gAbsIncModal.format(90)); writeThcCommand(false); } function onComment(message) { writeComment(message); } /** Force output of X, Y, and Z. */ function forceXYZ() { xOutput.reset(); yOutput.reset(); zOutput.reset(); } /** Force output of A, B, and C. */ function forceABC() { aOutput.reset(); bOutput.reset(); cOutput.reset(); } /** Force output of X, Y, Z, A, B, C, and F on next output. */ function forceAny() { forceXYZ(); forceABC(); } function onParameter(name, value) { } var currentWorkPlaneABC = undefined; function forceWorkPlane() { currentWorkPlaneABC = undefined; } var closestABC = false; // choose closest machine angles var currentMachineABC; function getWorkPlaneMachineABC(workPlane) { var W = workPlane; // map to global frame var abc = machineConfiguration.getABC(W); if (closestABC) { if (currentMachineABC) { abc = machineConfiguration.remapToABC(abc, currentMachineABC); } else { abc = machineConfiguration.getPreferredABC(abc); } } else { abc = machineConfiguration.getPreferredABC(abc); } try { abc = machineConfiguration.remapABC(abc); currentMachineABC = abc; } catch (e) { error( localize("Machine angles not supported") + ":" + conditional(machineConfiguration.isMachineCoordinate(0), " A" + abcFormat.format(abc.x)) + conditional(machineConfiguration.isMachineCoordinate(1), " B" + abcFormat.format(abc.y)) + conditional(machineConfiguration.isMachineCoordinate(2), " C" + abcFormat.format(abc.z)) ); } var direction = machineConfiguration.getDirection(abc); if (!isSameDirection(direction, W.forward)) { error(localize("Orientation not supported.")); return new Vector(); } if (!machineConfiguration.isABCSupported(abc)) { error( localize("Work plane is not supported") + ":" + conditional(machineConfiguration.isMachineCoordinate(0), " A" + abcFormat.format(abc.x)) + conditional(machineConfiguration.isMachineCoordinate(1), " B" + abcFormat.format(abc.y)) + conditional(machineConfiguration.isMachineCoordinate(2), " C" + abcFormat.format(abc.z)) ); } var tcp = false; if (tcp) { setRotation(W); // TCP mode } else { var O = machineConfiguration.getOrientation(abc); var R = machineConfiguration.getRemainingOrientation(abc, W); setRotation(R); } return abc; } function onSection() { writeln(""); if (hasParameter("operation-comment")) { var comment = getParameter("operation-comment"); if (comment) { writeComment(comment); } } switch (tool.type) { case TOOL_PLASMA_CUTTER: break; default: error(localize("The CNC does not support the required tool/process. Only plasma cutting is supported.")); return; } switch (currentSection.jetMode) { case JET_MODE_THROUGH: break; case JET_MODE_ETCHING: error(localize("Etch cutting mode is not supported.")); break; case JET_MODE_VAPORIZE: error(localize("Vaporize cutting mode is not supported.")); break; default: error(localize("Unsupported cutting mode.")); return; } { // 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); } // wcs if (currentSection.workOffset != currentWorkOffset) { writeBlock(currentSection.wcs); currentWorkOffset = currentSection.workOffset; } forceAny(); writeThcCommand(false); var initialPosition = getFramePosition(currentSection.getInitialPosition()); if (getProperty("useG0")) { writeBlock(gMotionModal.format(0), xOutput.format(initialPosition.x), yOutput.format(initialPosition.y)); } else { writeBlock(gMotionModal.format(1), xOutput.format(initialPosition.x), yOutput.format(initialPosition.y), feedOutput.format(highFeedrate)); } initialStraightProbe = true; writeStraightProbe(); if (getProperty("useZAxis")) { if (getProperty("useG0")) { writeBlock(gMotionModal.format(0), zOutput.format(initialPosition.z)); } else { writeBlock(gMotionModal.format(1), zOutput.format(initialPosition.z), feedOutput.format(highFeedrate)); } } } 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), "P" + secFormat.format(seconds)); } function onCycle() { } function getCommonCycle(x, y, z, r) { } function onCyclePoint(x, y, z) { } function onCycleEnd() { } var pendingRadiusCompensation = -1; function onRadiusCompensation() { pendingRadiusCompensation = radiusCompensation; } function writeStraightProbe() { if (getProperty("probe")) { writeThcCommand(false); var f = (hasParameter("operation:tool_feedEntry") ? getParameter("operation:tool_feedEntry") : toPreciseUnit(1000, MM)); writeBlock(g1Format.format(38.2), "Z" + xyzFormat.format(-100), feedOutput.format(f)); writeBlock(gFormat.format(92), "Z" + xyzFormat.format(getProperty("probeOffset"))); feedOutput.reset(); gMotionModal.reset(); } } function writeThcCommand(activate, feed) { if (activate && (feed >= getProperty("minThcFeed"))) { var thcCode = mThcModal.format(667); writeBlock(thcCode, conditional((getProperty("thcFeed") && thcCode), "F" + feedFormat.format(getProperty("thcFeed")))); } else { writeBlock(mThcModal.format(666)); } } var powerIsOn = false; function onPower(power) { initialStraightProbe = false; writeBlock(mFormat.format(power ? 3 : 5)); powerIsOn = power; if (power) { onDwell(getProperty("pierceDelay")); if (zFormat.isSignificant(getProperty("pierceHeight"))) { feedOutput.reset(); var f = (hasParameter("operation:tool_feedEntry") ? getParameter("operation:tool_feedEntry") : toPreciseUnit(1000, MM)); zFormat.setOffset(0); zOutput = createVariable({prefix:"Z"}, zFormat); writeBlock(gMotionModal.format(1), zOutput.format(getCurrentPosition().z), feedOutput.format(f)); } } else { if (zFormat.isSignificant(getProperty("pierceHeight"))) { zFormat.setOffset(getProperty("pierceHeight")); zOutput = createVariable({prefix:"Z"}, zFormat); } writeln(""); } } function onRapid(_x, _y, _z) { var x = xOutput.format(_x); var y = yOutput.format(_y); var z = zOutput.format(_z); // if plunge move, activate probe if enabled if (!x && !y && z && (_z < getCurrentPosition().z) && !initialStraightProbe && !powerIsOn) { writeStraightProbe(); } if (x || y || z) { if (pendingRadiusCompensation >= 0) { error(localize("Radius compensation mode cannot be changed at rapid traversal.")); return; } writeThcCommand(false); if (getProperty("useG0")) { writeBlock(gMotionModal.format(0), x, y, z); } else { writeBlock(gMotionModal.format(1), x, y, z, feedOutput.format(highFeedrate)); } feedOutput.reset(); } } function onLinear(_x, _y, _z, 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); var z = zOutput.format(_z); var f = feedOutput.format(feed); // if plunge move, activate probe if enabled if (!x && !y && z && (_z < getCurrentPosition().z) && !initialStraightProbe && !powerIsOn) { writeStraightProbe(); } writeThcCommand(!z, feed); if (x || y || (z && !powerIsOn)) { if (pendingRadiusCompensation >= 0) { error(localize("Radius compensation is not supported.")); pendingRadiusCompensation = -1; return; } else { writeBlock(gMotionModal.format(1), x, y, z, 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 onCircular(clockwise, cx, cy, cz, x, y, z, feed) { if (pendingRadiusCompensation >= 0) { error(localize("Radius compensation cannot be activated/deactivated for a circular move.")); return; } writeThcCommand(true, feed); var start = getCurrentPosition(); if (isFullCircle()) { if (isHelical()) { linearize(tolerance); return; } switch (getCircularPlane()) { case PLANE_XY: writeBlock(gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), feedOutput.format(feed)); break; default: linearize(tolerance); } } else { switch (getCircularPlane()) { case PLANE_XY: writeBlock(gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), feedOutput.format(feed)); break; default: linearize(tolerance); } } } var mapCommand = { COMMAND_STOP : 0, COMMAND_OPTIONAL_STOP: 1 }; function onCommand(command) { switch (command) { case COMMAND_POWER_ON: return; case COMMAND_POWER_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() { forceAny(); } /** Output block to do safe retract and/or move to home position. */ function writeRetract() { var words = []; // store all retracted axes in an array var retractAxes = new Array(false, false, false); var method = getProperty("safePositionMethod"); if (method == "clearanceHeight") { if (!is3D()) { error(localize("Safe retract option 'Clearance Height' is only supported when all operations are along the setup Z-axis.")); } return; } validate(arguments.length != 0, "No axis specified for writeRetract()."); for (i in arguments) { retractAxes[arguments[i]] = true; } if ((retractAxes[0] || retractAxes[1]) && !retracted) { // retract Z first before moving to X/Y home error(localize("Retracting in X/Y is not possible without being retracted in Z.")); return; } // special conditions /* if (retractAxes[2]) { // Z doesn't use G53 method = "G28"; } */ // define home positions var _xHome; var _yHome; var _zHome; if (method == "G28") { _xHome = toPreciseUnit(0, MM); _yHome = toPreciseUnit(0, MM); _zHome = toPreciseUnit(0, MM); } else { _xHome = machineConfiguration.hasHomePositionX() ? machineConfiguration.getHomePositionX() : toPreciseUnit(0, MM); _yHome = machineConfiguration.hasHomePositionY() ? machineConfiguration.getHomePositionY() : toPreciseUnit(0, MM); _zHome = machineConfiguration.getRetractPlane() != 0 ? machineConfiguration.getRetractPlane() : toPreciseUnit(0, MM); } for (var i = 0; i < arguments.length; ++i) { switch (arguments[i]) { case X: words.push("X" + xyzFormat.format(_xHome)); xOutput.reset(); break; case Y: words.push("Y" + xyzFormat.format(_yHome)); yOutput.reset(); break; case Z: words.push("Z" + xyzFormat.format(_zHome)); zOutput.reset(); retracted = true; break; default: error(localize("Unsupported axis specified for writeRetract().")); return; } } if (words.length > 0) { switch (method) { case "G28": gMotionModal.reset(); gAbsIncModal.reset(); writeBlock(gFormat.format(28), gAbsIncModal.format(91), words); writeBlock(gAbsIncModal.format(90)); break; case "G53": gMotionModal.reset(); writeBlock(gAbsIncModal.format(90), gFormat.format(53), gMotionModal.format(0), words); break; default: error(localize("Unsupported safe position method.")); return; } } } function onClose() { writeRetract(Z); writeRetract(X, Y); writeBlock(mFormat.format(30)); // stop program, spindle stop, coolant off } function setProperty(property, value) { properties[property].current = value; }