Last active
July 4, 2023 22:30
-
-
Save robanonymous/47bba09822a43e803aff410f49b30213 to your computer and use it in GitHub Desktop.
This a custom post processor for Autodesk Fusion 360 that has more options for the Sherline mill (I'm using 5400). To add this file on Mac: Right click on Fusion360 App in Applications, Select Show Package Contents - Navigate to Contents -> Libraries -> Applications -> CAM360 -> Data -> Posts, Grab and Drop File (Authenticate)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| Copyright (C) 2012-2015 by Autodesk, Inc. | |
| All rights reserved. | |
| LinuxCNC (EMC2) Sherline post processor configuration. | |
| $Revision: 00001 04fc0f7ff12e03d457d27cfcf3265dfc183241e5 $ | |
| $Date: 2016-10-08 13:46:56 $ | |
| FORKID {240C366F-30B2-4629-945B-8647E01614FC} | |
| */ | |
| description = "LinuxCNC (EMC2) for Sherline"; | |
| vendor = "Sherline"; | |
| vendorUrl = "http://www.sherline.com/"; | |
| legal = "Copyright (C) 2012-2015 by Autodesk, Inc."; | |
| certificationLevel = 2; | |
| minimumRevision = 24000; | |
| extension = "ngc"; | |
| setCodePage("ascii"); | |
| capabilities = CAPABILITY_MILLING; | |
| 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 = true; | |
| allowedCircularPlanes = undefined; // allow any circular motion | |
| // user-defined properties | |
| properties = { | |
| useHome: false, // uses homeX and homeY properties if true | |
| homeX: 0, // X safe home | |
| homeY: 0, // Y safe home | |
| homeZ: 1.00, // Z safe home, | |
| useAutomaticToolChanger: false, //skips the T# M6 tool command and corresponding G43 Z_ H_ offset parameter | |
| useManualToolChange: true, //uses the T# M6 tool command and skips corresponding G43 Z_ H_ offset parameter | |
| useSafetyRetracts: true, // whether or not to use G53 or G28 for retracting (in Z) between operations | |
| useWCS: false, // specifies if WCS (G54,G55,...) should be used or not | |
| useCoolant: false, // remove coolant commands | |
| useSpindleControl: false, // add spindle speed commands | |
| useFeedControl: true, // allow code control feed | |
| maxSpindleSpeed: 2800, // default speed for the Sherline 5400 mill. There is an attachment that allows it to go to 10,000 RPM though. | |
| useG28: false, // turn on to use G28 instead of G53 for machine retracts | |
| writeMachine: true, // write machine | |
| writeTools: true, // writes the tools | |
| preloadTool: false, // preloads next tool on tool change if any | |
| showSequenceNumbers: true, // show sequence numbers | |
| sequenceNumberStart: 10, // first sequence number | |
| sequenceNumberIncrement: 5, // increment for sequence numbers | |
| optionalStop: false, // optional stop | |
| separateWordsWithSpace: true, // specifies that the words should be separated with a white space | |
| useRadius: false, // specifies that arcs should be output using the radius (R word) instead of the I, J, and K words | |
| useParametricFeed: false, // specifies that feed should be output using Q values | |
| showNotes: false // specifies that operation notes should be output | |
| }; | |
| var permittedCommentChars = " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,=_-"; | |
| var mapCoolantTable = new Table( | |
| [9, 8, 7], | |
| {initial:COOLANT_OFF, force:true}, | |
| "Invalid coolant mode" | |
| ); | |
| var gFormat = createFormat({prefix:"G", decimals:1}); | |
| var mFormat = createFormat({prefix:"M", decimals:1}); | |
| var hFormat = createFormat({prefix:"H", decimals:1}); | |
| var dFormat = createFormat({prefix:"D", decimals:1}); | |
| var xyzFormat = createFormat({decimals:(unit == MM ? 3 : 4), forceDecimal:true}); | |
| var rFormat = xyzFormat; // radius | |
| var abcFormat = createFormat({decimals:3, forceDecimal:true, scale:DEG}); | |
| var feedFormat = createFormat({decimals:(unit == MM ? 2 : 3), forceDecimal:true}); | |
| var pitchFormat = createFormat({decimals:(unit == MM ? 3 : 4), forceDecimal:true}); | |
| var toolFormat = createFormat({decimals:0}); | |
| var rpmFormat = createFormat({decimals:0}); | |
| var secFormat = createFormat({decimals:3, forceDecimal:true}); // seconds - range 0.001-99999.999 | |
| var taperFormat = createFormat({decimals:1, scale:DEG}); | |
| var xOutput = createVariable({prefix:"X"}, xyzFormat); | |
| var yOutput = createVariable({prefix:"Y"}, xyzFormat); | |
| var zOutput = createVariable({prefix:"Z"}, xyzFormat); | |
| var aOutput = createVariable({prefix:"A"}, abcFormat); | |
| var bOutput = createVariable({prefix:"B"}, abcFormat); | |
| var cOutput = createVariable({prefix:"C"}, abcFormat); | |
| var feedOutput = createVariable({prefix:"F"}, feedFormat); | |
| var sOutput = createVariable({prefix:"S", force:true}, rpmFormat); | |
| var dOutput = createVariable({}, dFormat); | |
| // 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 gPlaneModal = createModal({onchange:function () {gMotionModal.reset();}}, gFormat); // modal group 2 // G17-19 | |
| var gAbsIncModal = createModal({}, gFormat); // modal group 3 // G90-91 | |
| var gFeedModeModal = createModal({}, gFormat); // modal group 5 // G93-94 | |
| var gUnitModal = createModal({}, gFormat); // modal group 6 // G20-21 | |
| var gCycleModal = createModal({}, gFormat); // modal group 9 // G81, ... | |
| var gRetractModal = createModal({}, gFormat); // modal group 10 // G98-99 | |
| // fixed settings | |
| var firstFeedParameter = 100; | |
| var WARNING_WORK_OFFSET = 0; | |
| // collected state | |
| var sequenceNumber; | |
| var currentWorkOffset; | |
| var forceSpindleSpeed = false; | |
| var activeMovements; // do not use by default | |
| var currentFeedId; | |
| /** | |
| Writes the specified block. | |
| */ | |
| function writeBlock() { | |
| if (properties.showSequenceNumbers) { | |
| writeWords2("N" + sequenceNumber, arguments); | |
| sequenceNumber += properties.sequenceNumberIncrement; | |
| if (sequenceNumber > 99999) { | |
| sequenceNumber = properties.sequenceNumberStart; | |
| } | |
| } else { | |
| writeWords(arguments); | |
| } | |
| } | |
| /** | |
| Writes the specified optional block. | |
| */ | |
| function writeOptionalBlock() { | |
| if (properties.showSequenceNumbers) { | |
| var words = formatWords(arguments); | |
| if (words) { | |
| writeWords("/", "N" + sequenceNumber, words); | |
| sequenceNumber += properties.sequenceNumberIncrement; | |
| if (sequenceNumber > 99999) { | |
| sequenceNumber = properties.sequenceNumberStart; | |
| } | |
| } | |
| } else { | |
| writeWords2("/", arguments); | |
| } | |
| } | |
| function formatComment(text) { | |
| return "(" + filterText(String(text).toUpperCase(), permittedCommentChars) + ")"; | |
| } | |
| /** | |
| Output a comment. | |
| */ | |
| function writeComment(text) { | |
| writeln(formatComment(text)); | |
| } | |
| function onOpen() { | |
| if (false) { // note: setup your machine here | |
| var aAxis = createAxis({coordinate:0, table:false, axis:[1, 0, 0], range:[-360,360], preference:1}); | |
| var cAxis = createAxis({coordinate:2, table:false, axis:[0, 0, 1], range:[-360,360], preference:1}); | |
| machineConfiguration = new MachineConfiguration(aAxis, cAxis); | |
| setMachineConfiguration(machineConfiguration); | |
| optimizeMachineAngles2(0); // TCP mode | |
| } | |
| //Set a custom home for X and Y | |
| if(properties.useHome){ | |
| machineConfiguration.setHomePositionX(homeX); | |
| machineConfiguration.setHomePositionY(homeY); | |
| } | |
| if (!machineConfiguration.isMachineCoordinate(0)) { | |
| aOutput.disable(); | |
| } | |
| if (!machineConfiguration.isMachineCoordinate(1)) { | |
| bOutput.disable(); | |
| } | |
| if (!machineConfiguration.isMachineCoordinate(2)) { | |
| cOutput.disable(); | |
| } | |
| if (!properties.separateWordsWithSpace) { | |
| setWordSeparator(""); | |
| } | |
| sequenceNumber = properties.sequenceNumberStart; | |
| writeln("%"); | |
| if (programName) { | |
| writeComment(programName); | |
| } | |
| if (programComment) { | |
| writeComment(programComment); | |
| } | |
| // dump machine configuration | |
| var vendor = machineConfiguration.getVendor(); | |
| var model = machineConfiguration.getModel(); | |
| var description = machineConfiguration.getDescription(); | |
| if (properties.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); | |
| } | |
| } | |
| // dump tool information | |
| if (properties.writeTools) { | |
| var zRanges = {}; | |
| if (is3D()) { | |
| var numberOfSections = getNumberOfSections(); | |
| for (var i = 0; i < numberOfSections; ++i) { | |
| var section = getSection(i); | |
| var zRange = section.getGlobalZRange(); | |
| var tool = section.getTool(); | |
| if (zRanges[tool.number]) { | |
| zRanges[tool.number].expandToRange(zRange); | |
| } else { | |
| zRanges[tool.number] = zRange; | |
| } | |
| } | |
| } | |
| var tools = getToolTable(); | |
| if (tools.getNumberOfTools() > 0) { | |
| for (var i = 0; i < tools.getNumberOfTools(); ++i) { | |
| var tool = tools.getTool(i); | |
| var comment = "T" + toolFormat.format(tool.number) + " " + | |
| "D=" + xyzFormat.format(tool.diameter) + " " + | |
| localize("CR") + "=" + xyzFormat.format(tool.cornerRadius); | |
| if ((tool.taperAngle > 0) && (tool.taperAngle < Math.PI)) { | |
| comment += " " + localize("TAPER") + "=" + taperFormat.format(tool.taperAngle) + localize("deg"); | |
| } | |
| if (zRanges[tool.number]) { | |
| comment += " - " + localize("ZMIN") + "=" + xyzFormat.format(zRanges[tool.number].getMinimum()); | |
| } | |
| comment += " - " + getToolTypeName(tool.type); | |
| writeComment(comment); | |
| } | |
| } | |
| } | |
| if (false) { | |
| // check for duplicate tool number | |
| for (var i = 0; i < getNumberOfSections(); ++i) { | |
| var sectioni = getSection(i); | |
| var tooli = sectioni.getTool(); | |
| for (var j = i + 1; j < getNumberOfSections(); ++j) { | |
| var sectionj = getSection(j); | |
| var toolj = sectionj.getTool(); | |
| if (tooli.number == toolj.number) { | |
| if (xyzFormat.areDifferent(tooli.diameter, toolj.diameter) || | |
| xyzFormat.areDifferent(tooli.cornerRadius, toolj.cornerRadius) || | |
| abcFormat.areDifferent(tooli.taperAngle, toolj.taperAngle) || | |
| (tooli.numberOfFlutes != toolj.numberOfFlutes)) { | |
| error( | |
| subst( | |
| localize("Using the same tool number for different cutter geometry for operation '%1' and '%2'."), | |
| sectioni.hasParameter("operation-comment") ? sectioni.getParameter("operation-comment") : ("#" + (i + 1)), | |
| sectionj.hasParameter("operation-comment") ? sectionj.getParameter("operation-comment") : ("#" + (j + 1)) | |
| ) | |
| ); | |
| return; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| // absolute coordinates, feed per min, and incremental arc center mode | |
| writeBlock(gAbsIncModal.format(90), gFeedModeModal.format(94), gPlaneModal.format(17), gFormat.format(91.1)); | |
| 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(); | |
| zOutput.reset(); | |
| } | |
| /** Force output of A, B, and C. */ | |
| function forceABC() { | |
| aOutput.reset(); | |
| bOutput.reset(); | |
| cOutput.reset(); | |
| } | |
| function forceFeed() { | |
| currentFeedId = undefined; | |
| feedOutput.reset(); | |
| } | |
| /** Force output of X, Y, Z, A, B, C, and F on next output. */ | |
| function forceAny() { | |
| forceXYZ(); | |
| forceABC(); | |
| forceFeed(); | |
| } | |
| function FeedContext(id, description, feed) { | |
| this.id = id; | |
| this.description = description; | |
| this.feed = feed; | |
| } | |
| function getFeed(f) { | |
| if (activeMovements) { | |
| var feedContext = activeMovements[movement]; | |
| if (feedContext != undefined) { | |
| if (!feedFormat.areDifferent(feedContext.feed, f)) { | |
| if (feedContext.id == currentFeedId) { | |
| return ""; // nothing has changed | |
| } | |
| forceFeed(); | |
| currentFeedId = feedContext.id; | |
| return "F#" + (firstFeedParameter + feedContext.id); | |
| } | |
| } | |
| currentFeedId = undefined; // force Q feed next time | |
| } | |
| if(properties.useFeedControl){ | |
| return feedOutput.format(f); // use feed value | |
| } else { | |
| return; | |
| } | |
| } | |
| function initializeActiveFeeds() { | |
| activeMovements = new Array(); | |
| var movements = currentSection.getMovements(); | |
| var id = 0; | |
| var activeFeeds = new Array(); | |
| if (hasParameter("operation:tool_feedCutting")) { | |
| if (movements & ((1 << MOVEMENT_CUTTING) | (1 << MOVEMENT_LINK_TRANSITION) | (1 << MOVEMENT_EXTENDED))) { | |
| var feedContext = new FeedContext(id, localize("Cutting"), getParameter("operation:tool_feedCutting")); | |
| activeFeeds.push(feedContext); | |
| activeMovements[MOVEMENT_CUTTING] = feedContext; | |
| activeMovements[MOVEMENT_LINK_TRANSITION] = feedContext; | |
| activeMovements[MOVEMENT_EXTENDED] = feedContext; | |
| } | |
| ++id; | |
| if (movements & (1 << MOVEMENT_PREDRILL)) { | |
| feedContext = new FeedContext(id, localize("Predrilling"), getParameter("operation:tool_feedCutting")); | |
| activeMovements[MOVEMENT_PREDRILL] = feedContext; | |
| activeFeeds.push(feedContext); | |
| } | |
| ++id; | |
| } | |
| if (hasParameter("operation:finishFeedrate")) { | |
| if (movements & (1 << MOVEMENT_FINISH_CUTTING)) { | |
| var feedContext = new FeedContext(id, localize("Finish"), getParameter("operation:finishFeedrate")); | |
| activeFeeds.push(feedContext); | |
| activeMovements[MOVEMENT_FINISH_CUTTING] = feedContext; | |
| } | |
| ++id; | |
| } else if (hasParameter("operation:tool_feedCutting")) { | |
| if (movements & (1 << MOVEMENT_FINISH_CUTTING)) { | |
| var feedContext = new FeedContext(id, localize("Finish"), getParameter("operation:tool_feedCutting")); | |
| activeFeeds.push(feedContext); | |
| activeMovements[MOVEMENT_FINISH_CUTTING] = feedContext; | |
| } | |
| ++id; | |
| } | |
| if (hasParameter("operation:tool_feedEntry")) { | |
| if (movements & (1 << MOVEMENT_LEAD_IN)) { | |
| var feedContext = new FeedContext(id, localize("Entry"), getParameter("operation:tool_feedEntry")); | |
| activeFeeds.push(feedContext); | |
| activeMovements[MOVEMENT_LEAD_IN] = feedContext; | |
| } | |
| ++id; | |
| } | |
| if (hasParameter("operation:tool_feedExit")) { | |
| if (movements & (1 << MOVEMENT_LEAD_OUT)) { | |
| var feedContext = new FeedContext(id, localize("Exit"), getParameter("operation:tool_feedExit")); | |
| activeFeeds.push(feedContext); | |
| activeMovements[MOVEMENT_LEAD_OUT] = feedContext; | |
| } | |
| ++id; | |
| } | |
| if (hasParameter("operation:noEngagementFeedrate")) { | |
| if (movements & (1 << MOVEMENT_LINK_DIRECT)) { | |
| var feedContext = new FeedContext(id, localize("Direct"), getParameter("operation:noEngagementFeedrate")); | |
| activeFeeds.push(feedContext); | |
| activeMovements[MOVEMENT_LINK_DIRECT] = feedContext; | |
| } | |
| ++id; | |
| } else if (hasParameter("operation:tool_feedCutting") && | |
| hasParameter("operation:tool_feedEntry") && | |
| hasParameter("operation:tool_feedExit")) { | |
| if (movements & (1 << MOVEMENT_LINK_DIRECT)) { | |
| var feedContext = new FeedContext(id, localize("Direct"), Math.max(getParameter("operation:tool_feedCutting"), getParameter("operation:tool_feedEntry"), getParameter("operation:tool_feedExit"))); | |
| activeFeeds.push(feedContext); | |
| activeMovements[MOVEMENT_LINK_DIRECT] = feedContext; | |
| } | |
| ++id; | |
| } | |
| if (hasParameter("operation:reducedFeedrate")) { | |
| if (movements & (1 << MOVEMENT_REDUCED)) { | |
| var feedContext = new FeedContext(id, localize("Reduced"), getParameter("operation:reducedFeedrate")); | |
| activeFeeds.push(feedContext); | |
| activeMovements[MOVEMENT_REDUCED] = feedContext; | |
| } | |
| ++id; | |
| } | |
| if (hasParameter("operation:tool_feedRamp")) { | |
| if (movements & ((1 << MOVEMENT_RAMP) | (1 << MOVEMENT_RAMP_HELIX) | (1 << MOVEMENT_RAMP_PROFILE) | (1 << MOVEMENT_RAMP_ZIG_ZAG))) { | |
| var feedContext = new FeedContext(id, localize("Ramping"), getParameter("operation:tool_feedRamp")); | |
| activeFeeds.push(feedContext); | |
| activeMovements[MOVEMENT_RAMP] = feedContext; | |
| activeMovements[MOVEMENT_RAMP_HELIX] = feedContext; | |
| activeMovements[MOVEMENT_RAMP_PROFILE] = feedContext; | |
| activeMovements[MOVEMENT_RAMP_ZIG_ZAG] = feedContext; | |
| } | |
| ++id; | |
| } | |
| if (hasParameter("operation:tool_feedPlunge")) { | |
| if (movements & (1 << MOVEMENT_PLUNGE)) { | |
| var feedContext = new FeedContext(id, localize("Plunge"), getParameter("operation:tool_feedPlunge")); | |
| activeFeeds.push(feedContext); | |
| activeMovements[MOVEMENT_PLUNGE] = feedContext; | |
| } | |
| ++id; | |
| } | |
| if (true) { // high feed | |
| if (movements & (1 << MOVEMENT_HIGH_FEED)) { | |
| var feedContext = new FeedContext(id, localize("High Feed"), this.highFeedrate); | |
| activeFeeds.push(feedContext); | |
| activeMovements[MOVEMENT_HIGH_FEED] = feedContext; | |
| } | |
| ++id; | |
| } | |
| for (var i = 0; i < activeFeeds.length; ++i) { | |
| var feedContext = activeFeeds[i]; | |
| writeBlock("#" + (firstFeedParameter + feedContext.id) + "=" + feedFormat.format(feedContext.feed), formatComment(feedContext.description)); | |
| } | |
| } | |
| var currentWorkPlaneABC = undefined; | |
| function forceWorkPlane() { | |
| currentWorkPlaneABC = undefined; | |
| } | |
| function setWorkPlane(abc) { | |
| if (!machineConfiguration.isMultiAxisConfiguration()) { | |
| return; // ignore | |
| } | |
| if (!((currentWorkPlaneABC == undefined) || | |
| abcFormat.areDifferent(abc.x, currentWorkPlaneABC.x) || | |
| abcFormat.areDifferent(abc.y, currentWorkPlaneABC.y) || | |
| abcFormat.areDifferent(abc.z, currentWorkPlaneABC.z))) { | |
| return; // no change | |
| } | |
| onCommand(COMMAND_UNLOCK_MULTI_AXIS); | |
| // NOTE: add retract here | |
| writeBlock( | |
| gMotionModal.format(0), | |
| 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)) | |
| ); | |
| onCommand(COMMAND_LOCK_MULTI_AXIS); | |
| currentWorkPlaneABC = abc; | |
| } | |
| 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.")); | |
| } | |
| 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 = true; | |
| if (tcp) { | |
| setRotation(W); // TCP mode | |
| } else { | |
| var O = machineConfiguration.getOrientation(abc); | |
| var R = machineConfiguration.getRemainingOrientation(abc, W); | |
| setRotation(R); | |
| } | |
| return abc; | |
| } | |
| 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()); | |
| if (insertToolCall || newWorkOffset || newWorkPlane) { | |
| // stop spindle before retract during tool change | |
| if (insertToolCall && !isFirstSection()) { | |
| if(properties.useSpindleControl){ | |
| onCommand(COMMAND_STOP_SPINDLE); | |
| } | |
| } | |
| if (properties.useSafetyRetracts || properties.useManualToolChange) { | |
| // retract to safe plane | |
| retracted = true; | |
| if (properties.useG28) { | |
| writeBlock(gFormat.format(28), gAbsIncModal.format(91), "Z" + xyzFormat.format(properties.homeZ)); // retract | |
| writeBlock(gAbsIncModal.format(90)); | |
| } else { | |
| writeBlock(gAbsIncModal.format(90), gFormat.format(53), gMotionModal.format(0), "Z" + xyzFormat.format(properties.homeZ)); // retract | |
| } | |
| zOutput.reset(); | |
| } | |
| } | |
| if (hasParameter("operation-comment")) { | |
| var comment = getParameter("operation-comment"); | |
| if (comment) { | |
| writeComment(comment); | |
| } | |
| } | |
| if (properties.showNotes && hasParameter("notes")) { | |
| var notes = getParameter("notes"); | |
| if (notes) { | |
| var lines = String(notes).split("\n"); | |
| var r1 = new RegExp("^[\\s]+", "g"); | |
| var r2 = new RegExp("[\\s]+$", "g"); | |
| for (line in lines) { | |
| var comment = lines[line].replace(r1, "").replace(r2, ""); | |
| if (comment) { | |
| writeComment(comment); | |
| } | |
| } | |
| } | |
| } | |
| if (insertToolCall) { | |
| forceWorkPlane(); | |
| retracted = true; | |
| if(properties.useCoolant){ | |
| onCommand(COMMAND_COOLANT_OFF); | |
| } | |
| if (!isFirstSection() && properties.optionalStop) { | |
| onCommand(COMMAND_OPTIONAL_STOP); | |
| } | |
| if (tool.number > 99) { | |
| warning(localize("Tool number exceeds maximum value.")); | |
| } | |
| if(properties.useAutomaticToolChanger || properties.useManualToolChange){ | |
| writeBlock("T" + toolFormat.format(tool.number), mFormat.format(6)); | |
| } | |
| if (tool.comment) { | |
| writeComment(tool.comment); | |
| } | |
| var showToolZMin = false; | |
| if (showToolZMin) { | |
| if (is3D()) { | |
| var numberOfSections = getNumberOfSections(); | |
| var zRange = currentSection.getGlobalZRange(); | |
| var number = tool.number; | |
| for (var i = currentSection.getId() + 1; i < numberOfSections; ++i) { | |
| var section = getSection(i); | |
| if (section.getTool().number != number) { | |
| break; | |
| } | |
| zRange.expandToRange(section.getGlobalZRange()); | |
| } | |
| writeComment(localize("ZMIN") + "=" + zRange.getMinimum()); | |
| } | |
| } | |
| if(properties.useAutomaticToolChanger){ | |
| if (properties.preloadTool) { | |
| var nextTool = getNextTool(tool.number); | |
| if (nextTool) { | |
| writeBlock("T" + toolFormat.format(nextTool.number)); | |
| } else { | |
| // preload first tool | |
| var section = getSection(0); | |
| var firstToolNumber = section.getTool().number; | |
| if (tool.number != firstToolNumber) { | |
| writeBlock("T" + toolFormat.format(firstToolNumber)); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| if(properties.useSpindleControl){ | |
| if (insertToolCall || | |
| forceSpindleSpeed || | |
| isFirstSection() || | |
| (rpmFormat.areDifferent(tool.spindleRPM, sOutput.getCurrent())) || | |
| (tool.clockwise != getPreviousSection().getTool().clockwise)) { | |
| forceSpindleSpeed = false; | |
| if (tool.spindleRPM < 1) { | |
| error(localize("Spindle speed out of range.")); | |
| return; | |
| } | |
| if (tool.spindleRPM > properties.maxSpindleSpeed) { | |
| warning(localize("Spindle speed exceeds maximum value.")); | |
| } | |
| writeBlock( | |
| sOutput.format(tool.spindleRPM), mFormat.format(tool.clockwise ? 3 : 4) | |
| ); | |
| } | |
| } | |
| if (properties.useWCS) { | |
| // wcs | |
| if (insertToolCall) { // force work offset when changing tool | |
| currentWorkOffset = undefined; | |
| } | |
| var workOffset = currentSection.workOffset; | |
| if (workOffset == 0) { | |
| warningOnce(localize("Work offset has not been specified. Using G54 as WCS."), WARNING_WORK_OFFSET); | |
| workOffset = 1; | |
| } | |
| if (workOffset > 0) { | |
| if (workOffset > 6) { | |
| var p = workOffset - 6; // 1->... | |
| if (p > 3) { | |
| error(localize("Work offset out of range.")); | |
| return; | |
| } else { | |
| if (workOffset != currentWorkOffset) { | |
| writeBlock(gFormat.format(59.1), "P" + p); // G59.1P | |
| currentWorkOffset = workOffset; | |
| } | |
| } | |
| } else { | |
| if (workOffset != currentWorkOffset) { | |
| writeBlock(gFormat.format(53 + workOffset)); // G54->G59 | |
| currentWorkOffset = workOffset; | |
| } | |
| } | |
| } | |
| } | |
| forceXYZ(); | |
| if (machineConfiguration.isMultiAxisConfiguration()) { // use 5-axis indexing for multi-axis mode | |
| // set working plane after datum shift | |
| var abc = new Vector(0, 0, 0); | |
| if (currentSection.isMultiAxis()) { | |
| forceWorkPlane(); | |
| cancelTransformation(); | |
| } else { | |
| abc = getWorkPlaneMachineABC(currentSection.workPlane); | |
| } | |
| setWorkPlane(abc); | |
| } else { // 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); | |
| } | |
| // set coolant after we have positioned at Z | |
| if(properties.useCoolant) { | |
| var c = mapCoolantTable.lookup(tool.coolant); | |
| if (c) { | |
| writeBlock(mFormat.format(c)); | |
| } else { | |
| warning(localize("Coolant not supported.")); | |
| } | |
| } | |
| forceAny(); | |
| gMotionModal.reset(); | |
| var initialPosition = getFramePosition(currentSection.getInitialPosition()); | |
| if (!retracted) { | |
| if (getCurrentPosition().z < initialPosition.z) { | |
| writeBlock(gMotionModal.format(0), zOutput.format(initialPosition.z)); | |
| } | |
| } | |
| if(properties.useAutomaticToolChanger){ | |
| if (insertToolCall || retracted || (!isFirstSection() && getPreviousSection().isMultiAxis()) ) { | |
| var lengthOffset = tool.lengthOffset; | |
| if (lengthOffset > 99) { | |
| error(localize("Length offset out of range.")); | |
| return; | |
| } | |
| gMotionModal.reset(); | |
| writeBlock(gPlaneModal.format(17)); | |
| if (!machineConfiguration.isHeadConfiguration()) { | |
| writeBlock( | |
| gAbsIncModal.format(90), | |
| gMotionModal.format(0), xOutput.format(initialPosition.x), yOutput.format(initialPosition.y) | |
| ); | |
| writeBlock(gMotionModal.format(0), gFormat.format(43), zOutput.format(initialPosition.z), hFormat.format(lengthOffset)); | |
| } else { | |
| writeBlock( | |
| gAbsIncModal.format(90), | |
| gMotionModal.format(0), | |
| gFormat.format(43), xOutput.format(initialPosition.x), | |
| yOutput.format(initialPosition.y), | |
| zOutput.format(initialPosition.z), hFormat.format(lengthOffset) | |
| ); | |
| } | |
| gMotionModal.reset(); | |
| } else { | |
| writeBlock( | |
| gAbsIncModal.format(90), | |
| gMotionModal.format(0), | |
| xOutput.format(initialPosition.x), | |
| yOutput.format(initialPosition.y) | |
| ); | |
| } | |
| } | |
| if (properties.useParametricFeed && | |
| hasParameter("operation-strategy") && | |
| (getParameter("operation-strategy") != "drill")) { | |
| if (!insertToolCall && | |
| activeMovements && | |
| (getCurrentSectionId() > 0) && | |
| (getPreviousSection().getPatternId() == currentSection.getPatternId())) { | |
| // use the current feeds | |
| } else { | |
| initializeActiveFeeds(); | |
| } | |
| } else { | |
| activeMovements = undefined; | |
| } | |
| } | |
| function onDwell(seconds) { | |
| if (seconds > 99999.999) { | |
| warning(localize("Dwelling time is out of range.")); | |
| } | |
| writeBlock(gFeedModeModal.format(94), gFormat.format(4), "P" + secFormat.format(seconds)); | |
| } | |
| function onSpindleSpeed(spindleSpeed) { | |
| writeBlock(sOutput.format(spindleSpeed)); | |
| } | |
| function onCycle() { | |
| writeBlock(gPlaneModal.format(17)); | |
| } | |
| function getCommonCycle(x, y, z, r) { | |
| forceXYZ(); // force xyz on first drill hole of any cycle | |
| return [xOutput.format(x), yOutput.format(y), | |
| zOutput.format(z), | |
| "R" + xyzFormat.format(r)]; | |
| } | |
| function onCyclePoint(x, y, z) { | |
| switch (cycleType) { | |
| case "tapping": | |
| case "left-tapping": | |
| case "right-tapping": | |
| cycleExpanded = true; | |
| repositionToCycleClearance(cycle, x, y, z); | |
| writeBlock( | |
| gAbsIncModal.format(90), gMotionModal.format(0), | |
| conditional(gPlaneModal.getCurrent() == 17, zOutput.format(cycle.retract)), | |
| conditional(gPlaneModal.getCurrent() == 18, yOutput.format(cycle.retract)), | |
| conditional(gPlaneModal.getCurrent() == 19, xOutput.format(cycle.retract)) | |
| ); | |
| writeBlock( | |
| gAbsIncModal.format(90), gFormat.format(33.1), | |
| conditional(gPlaneModal.getCurrent() == 17, zOutput.format(z)), | |
| conditional(gPlaneModal.getCurrent() == 18, yOutput.format(y)), | |
| conditional(gPlaneModal.getCurrent() == 19, xOutput.format(x)), | |
| "K" + pitchFormat.format(tool.threadPitch) | |
| ); | |
| gMotionModal.reset(); | |
| writeBlock( | |
| gAbsIncModal.format(90), gMotionModal.format(0), | |
| conditional(gPlaneModal.getCurrent() == 17, zOutput.format(cycle.clearance)), | |
| conditional(gPlaneModal.getCurrent() == 18, yOutput.format(cycle.clearance)), | |
| conditional(gPlaneModal.getCurrent() == 19, xOutput.format(cycle.clearance)) | |
| ); | |
| return; | |
| /* | |
| case "tapping-with-chip-breaking": | |
| case "left-tapping-with-chip-breaking": | |
| case "right-tapping-with-chip-breaking": | |
| */ | |
| } | |
| if (isFirstCyclePoint()) { | |
| repositionToCycleClearance(cycle, x, y, z); | |
| // return to initial Z which is clearance plane and set absolute mode | |
| var F = cycle.feedrate; | |
| var P = (cycle.dwell == 0) ? 0 : clamp(0.001, cycle.dwell, 99999999); // in seconds | |
| switch (cycleType) { | |
| case "drilling": | |
| writeBlock( | |
| gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(81), | |
| getCommonCycle(x, y, z, cycle.retract), | |
| feedOutput.format(F) | |
| ); | |
| break; | |
| case "counter-boring": | |
| if (P > 0) { | |
| writeBlock( | |
| gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(82), | |
| getCommonCycle(x, y, z, cycle.retract), | |
| "P" + secFormat.format(P), | |
| feedOutput.format(F) | |
| ); | |
| } else { | |
| writeBlock( | |
| gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(81), | |
| getCommonCycle(x, y, z, cycle.retract), | |
| feedOutput.format(F) | |
| ); | |
| } | |
| break; | |
| case "chip-breaking": | |
| expandCyclePoint(x, y, z); | |
| break; | |
| case "deep-drilling": | |
| if (P > 0) { | |
| expandCyclePoint(x, y, z); | |
| } else { | |
| writeBlock( | |
| gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(83), | |
| getCommonCycle(x, y, z, cycle.retract), | |
| "Q" + xyzFormat.format(cycle.incrementalDepth), | |
| // conditional(P > 0, "P" + secFormat.format(P)), | |
| feedOutput.format(F) | |
| ); | |
| } | |
| break; | |
| case "fine-boring": | |
| expandCyclePoint(x, y, z); | |
| break; | |
| /* // not supported | |
| case "back-boring": | |
| var dx = (gPlaneModal.getCurrent() == 19) ? cycle.backBoreDistance : 0; | |
| var dy = (gPlaneModal.getCurrent() == 18) ? cycle.backBoreDistance : 0; | |
| var dz = (gPlaneModal.getCurrent() == 17) ? cycle.backBoreDistance : 0; | |
| writeBlock( | |
| gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(87), | |
| getCommonCycle(x - dx, y - dy, z - dz, cycle.bottom), | |
| "Q" + xyzFormat.format(cycle.shift), | |
| "P" + secFormat.format(P), // not optional | |
| feedOutput.format(F) | |
| ); | |
| break; | |
| */ | |
| case "reaming": | |
| if (P > 0) { | |
| writeBlock( | |
| gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(89), | |
| getCommonCycle(x, y, z, cycle.retract), | |
| "P" + secFormat.format(P), | |
| feedOutput.format(F) | |
| ); | |
| } else { | |
| writeBlock( | |
| gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(85), | |
| getCommonCycle(x, y, z, cycle.retract), | |
| feedOutput.format(F) | |
| ); | |
| } | |
| break; | |
| case "stop-boring": | |
| writeBlock( | |
| gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(86), | |
| getCommonCycle(x, y, z, cycle.retract), | |
| conditional(P > 0, "P" + secFormat.format(P)), | |
| feedOutput.format(F) | |
| ); | |
| break; | |
| case "manual-boring": | |
| writeBlock( | |
| gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(88), | |
| getCommonCycle(x, y, z, cycle.retract), | |
| "P" + secFormat.format(P), // not optional | |
| feedOutput.format(F) | |
| ); | |
| break; | |
| case "boring": | |
| if (P > 0) { | |
| writeBlock( | |
| gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(89), | |
| getCommonCycle(x, y, z, cycle.retract), | |
| "P" + secFormat.format(P), // not optional | |
| feedOutput.format(F) | |
| ); | |
| } else { | |
| writeBlock( | |
| gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(85), | |
| getCommonCycle(x, y, z, cycle.retract), | |
| feedOutput.format(F) | |
| ); | |
| } | |
| break; | |
| default: | |
| expandCyclePoint(x, y, z); | |
| } | |
| } else { | |
| if (cycleExpanded) { | |
| expandCyclePoint(x, y, z); | |
| } else { | |
| var _x = xOutput.format(x); | |
| var _y = yOutput.format(y); | |
| var _z = zOutput.format(z); | |
| if (!_x && !_y && !_z) { | |
| switch (gPlaneModal.getCurrent()) { | |
| case 17: // XY | |
| xOutput.reset(); // at least one axis is required | |
| _x = xOutput.format(x); | |
| break; | |
| case 18: // ZX | |
| zOutput.reset(); // at least one axis is required | |
| _z = zOutput.format(z); | |
| break; | |
| case 19: // YZ | |
| yOutput.reset(); // at least one axis is required | |
| _y = yOutput.format(y); | |
| break; | |
| } | |
| } | |
| writeBlock(_x, _y, _z); | |
| } | |
| } | |
| } | |
| function onCycleEnd() { | |
| if (!cycleExpanded) { | |
| writeBlock(gCycleModal.format(80)); | |
| gMotionModal.reset(); | |
| } | |
| } | |
| var pendingRadiusCompensation = -1; | |
| function onRadiusCompensation() { | |
| pendingRadiusCompensation = radiusCompensation; | |
| } | |
| function onRapid(_x, _y, _z) { | |
| var x = xOutput.format(_x); | |
| var y = yOutput.format(_y); | |
| var z = zOutput.format(_z); | |
| if (x || y || z) { | |
| if (pendingRadiusCompensation >= 0) { | |
| error(localize("Radius compensation mode cannot be changed at rapid traversal.")); | |
| return; | |
| } | |
| writeBlock(gMotionModal.format(0), x, y, z); | |
| forceFeed(); | |
| } | |
| } | |
| function onLinear(_x, _y, _z, feed) { | |
| var x = xOutput.format(_x); | |
| var y = yOutput.format(_y); | |
| var z = zOutput.format(_z); | |
| var f = getFeed(feed); | |
| if (x || y || z) { | |
| if (pendingRadiusCompensation >= 0) { | |
| pendingRadiusCompensation = -1; | |
| var d = tool.diameterOffset; | |
| if (d > 99) { | |
| warning(localize("The diameter offset exceeds the maximum value.")); | |
| } | |
| writeBlock(gPlaneModal.format(17)); | |
| switch (radiusCompensation) { | |
| case RADIUS_COMPENSATION_LEFT: | |
| dOutput.reset(); | |
| writeBlock(gMotionModal.format(1), gFormat.format(41), x, y, z, dOutput.format(d), f); | |
| break; | |
| case RADIUS_COMPENSATION_RIGHT: | |
| dOutput.reset(); | |
| writeBlock(gMotionModal.format(1), gFormat.format(42), x, y, z, dOutput.format(d), f); | |
| break; | |
| default: | |
| writeBlock(gMotionModal.format(1), gFormat.format(40), x, y, z, f); | |
| } | |
| } else { | |
| writeBlock(gMotionModal.format(1), x, y, z, f); | |
| } | |
| } else if (f) { | |
| if (getNextRecord().isMotion()) { // try not to output feed without motion | |
| forceFeed(); // force feed on next line | |
| } else { | |
| writeBlock(gMotionModal.format(1), f); | |
| } | |
| } | |
| } | |
| function onRapid5D(_x, _y, _z, _a, _b, _c) { | |
| if (!currentSection.isOptimizedForMachine()) { | |
| error(localize("This post configuration has not been customized for 5-axis simultaneous toolpath.")); | |
| return; | |
| } | |
| if (pendingRadiusCompensation >= 0) { | |
| error(localize("Radius compensation mode cannot be changed at rapid traversal.")); | |
| return; | |
| } | |
| var x = xOutput.format(_x); | |
| var y = yOutput.format(_y); | |
| var z = zOutput.format(_z); | |
| var a = aOutput.format(_a); | |
| var b = bOutput.format(_b); | |
| var c = cOutput.format(_c); | |
| writeBlock(gMotionModal.format(0), x, y, z, a, b, c); | |
| forceFeed(); | |
| } | |
| function onLinear5D(_x, _y, _z, _a, _b, _c, feed) { | |
| if (!currentSection.isOptimizedForMachine()) { | |
| error(localize("This post configuration has not been customized for 5-axis simultaneous toolpath.")); | |
| return; | |
| } | |
| if (pendingRadiusCompensation >= 0) { | |
| error(localize("Radius compensation cannot be activated/deactivated for 5-axis move.")); | |
| return; | |
| } | |
| var x = xOutput.format(_x); | |
| var y = yOutput.format(_y); | |
| var z = zOutput.format(_z); | |
| var a = aOutput.format(_a); | |
| var b = bOutput.format(_b); | |
| var c = cOutput.format(_c); | |
| var f = getFeed(feed); | |
| if (x || y || z || a || b || c) { | |
| if(properties.useFeedControl){ | |
| writeBlock(gMotionModal.format(1), x, y, z, a, b, c, f); | |
| } else { | |
| writeBlock(gMotionModal.format(1), x, y, z, a, b, c); | |
| } | |
| } else if (f) { | |
| if (getNextRecord().isMotion()) { // try not to output feed without motion | |
| forceFeed(); // force feed on next line | |
| } else { | |
| if(properties.useFeedControl){ | |
| writeBlock(gMotionModal.format(1), f); | |
| } else { | |
| writeBlock(gMotionModal.format(1)); | |
| } | |
| } | |
| } | |
| } | |
| 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; | |
| } | |
| var start = getCurrentPosition(); | |
| if (isFullCircle()) { | |
| if (properties.useRadius || isHelical()) { // radius mode does not support full arcs | |
| linearize(tolerance); | |
| return; | |
| } | |
| switch (getCircularPlane()) { | |
| case PLANE_XY: | |
| writeBlock(gAbsIncModal.format(90), gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), getFeed(feed)); | |
| break; | |
| case PLANE_ZX: | |
| writeBlock(gAbsIncModal.format(90), gPlaneModal.format(18), gMotionModal.format(clockwise ? 2 : 3), iOutput.format(cx - start.x, 0), kOutput.format(cz - start.z, 0), getFeed(feed)); | |
| break; | |
| case PLANE_YZ: | |
| writeBlock(gAbsIncModal.format(90), gPlaneModal.format(19), gMotionModal.format(clockwise ? 2 : 3), jOutput.format(cy - start.y, 0), kOutput.format(cz - start.z, 0), getFeed(feed)); | |
| break; | |
| default: | |
| linearize(tolerance); | |
| } | |
| } else if (!properties.useRadius) { | |
| switch (getCircularPlane()) { | |
| case PLANE_XY: | |
| writeBlock(gAbsIncModal.format(90), gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), getFeed(feed)); | |
| break; | |
| case PLANE_ZX: | |
| writeBlock(gAbsIncModal.format(90), gPlaneModal.format(18), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), iOutput.format(cx - start.x, 0), kOutput.format(cz - start.z, 0), getFeed(feed)); | |
| break; | |
| case PLANE_YZ: | |
| writeBlock(gAbsIncModal.format(90), gPlaneModal.format(19), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), jOutput.format(cy - start.y, 0), kOutput.format(cz - start.z, 0), getFeed(feed)); | |
| break; | |
| default: | |
| linearize(tolerance); | |
| } | |
| } else { // use radius mode | |
| var r = getCircularRadius(); | |
| if (toDeg(getCircularSweep()) > (180 + 1e-9)) { | |
| r = -r; // allow up to <360 deg arcs | |
| } | |
| switch (getCircularPlane()) { | |
| case PLANE_XY: | |
| writeBlock(gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), "R" + rFormat.format(r), getFeed(feed)); | |
| break; | |
| case PLANE_ZX: | |
| writeBlock(gPlaneModal.format(18), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), "R" + rFormat.format(r), getFeed(feed)); | |
| break; | |
| case PLANE_YZ: | |
| writeBlock(gPlaneModal.format(19), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), "R" + rFormat.format(r), getFeed(feed)); | |
| break; | |
| default: | |
| linearize(tolerance); | |
| } | |
| } | |
| } | |
| var mapCommand = { | |
| COMMAND_STOP:0, | |
| COMMAND_OPTIONAL_STOP:1, | |
| COMMAND_END:2, | |
| COMMAND_SPINDLE_CLOCKWISE:3, | |
| COMMAND_SPINDLE_COUNTERCLOCKWISE:4, | |
| COMMAND_STOP_SPINDLE:5, | |
| COMMAND_ORIENTATE_SPINDLE:19, | |
| COMMAND_LOAD_TOOL:6, | |
| COMMAND_COOLANT_ON:8, | |
| COMMAND_COOLANT_OFF:9 | |
| }; | |
| function onCommand(command) { | |
| switch (command) { | |
| case COMMAND_STOP: | |
| writeBlock(mFormat.format(0)); | |
| forceSpindleSpeed = true; | |
| return; | |
| case COMMAND_START_SPINDLE: | |
| onCommand(tool.clockwise ? COMMAND_SPINDLE_CLOCKWISE : COMMAND_SPINDLE_COUNTERCLOCKWISE); | |
| 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() { | |
| if (currentSection.isMultiAxis()) { | |
| writeBlock(gMotionModal.format(49)); | |
| } | |
| writeBlock(gPlaneModal.format(17)); | |
| if (((getCurrentSectionId() + 1) >= getNumberOfSections()) || (tool.number != getNextSection().getTool().number)) { | |
| onCommand(COMMAND_BREAK_CONTROL); | |
| } | |
| forceAny(); | |
| } | |
| function onClose() { | |
| if (properties.useCoolant) { | |
| onCommand(COMMAND_COOLANT_OFF); | |
| } | |
| if (properties.useSafetyRetracts) { | |
| if (properties.useG28) { | |
| writeBlock(gFormat.format(28), gAbsIncModal.format(91), "Z" + xyzFormat.format(properties.homeZ)); // retract | |
| } else { | |
| writeBlock(gAbsIncModal.format(90), gFormat.format(53), gMotionModal.format(0), "Z" + xyzFormat.format(properties.homeZ)); // retract | |
| } | |
| zOutput.reset(); | |
| } | |
| setWorkPlane(new Vector(0, 0, 0)); // reset working plane | |
| if (!machineConfiguration.hasHomePositionX() && !machineConfiguration.hasHomePositionY()) { | |
| if (properties.useG28) { | |
| // 90/91 mode is don't care | |
| writeBlock(gFormat.format(28), gAbsIncModal.format(91), "X" + xyzFormat.format(0), "Y" + xyzFormat.format(0)); // return to home | |
| } | |
| } else { | |
| if(properties.useHome){ | |
| var homeX; | |
| if (machineConfiguration.hasHomePositionX()) { | |
| homeX = "X" + xyzFormat.format(machineConfiguration.getHomePositionX()); | |
| } | |
| var homeY; | |
| if (machineConfiguration.hasHomePositionY()) { | |
| homeY = "Y" + xyzFormat.format(machineConfiguration.getHomePositionY()); | |
| } | |
| writeBlock(gAbsIncModal.format(90), gFormat.format(53), gMotionModal.format(0), homeX, homeY); | |
| } | |
| } | |
| onImpliedCommand(COMMAND_END); | |
| if(properties.useSpindleControl){ | |
| onImpliedCommand(COMMAND_STOP_SPINDLE); | |
| } | |
| writeBlock(mFormat.format(30)); // stop program, spindle stop, coolant off | |
| writeln("%"); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment