/** Copyright (C) 2012-2025 by Autodesk, Inc. All rights reserved. Roland post processor configuration. $Revision: 44192 ed560ad487cef22ddd887ddb3fba38f6ac9c1903 $ $Date: 2025-08-26 06:37:41 $ FORKID {C1E71A5D-CAD6-45ba-B223-FE41348C147E} */ description = "Roland RML"; vendor = "Roland DG"; vendorUrl = "http://www.rolanddg.com"; legal = "Copyright (C) 2012-2025 by Autodesk, Inc."; certificationLevel = 2; minimumRevision = 45917; longDescription = "Generic post for Roland RML. By default the post will output code for MDX-15 and MDX-20. Other MDXs work if you select the correct machine model and options using the 'Machine type' property."; extension = "prn"; programNameIsInteger = true; setCodePage("ascii"); capabilities = CAPABILITY_MILLING | CAPABILITY_MACHINE_SIMULATION; 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 = true; allowedCircularPlanes = undefined; // allow any circular motion highFeedrate = (unit == MM) ? 5000 : 200; // user-defined properties properties = { machineModel: { title : "Machine type", description: "Sets the machine type.", group : "configuration", type : "enum", values : [ {id:"mdx-15/20", title:"MDX-15/20"}, {id:"mdx-40", title:"MDX-40"}, {id:"mdx-50", title:"MDX-50"}, {id:"mdx-540", title:"MDX-540"} ], value: "mdx-15/20", scope: "post" }, useToolCall: { title : "Use tool changer", description: "Specifies that a tool changer is available.", group : "preferences", type : "boolean", value : false, scope : "post" }, spindleSpeedInRPM: { title : "Spindle speed in RPM", description: "If enabled, the spindle speed is outputted with the RPM format rather than the RC spindle speed codes.", group : "preferences", type : "boolean", value : false, scope : "post" }, rotaryTableAxis: { title : "Rotary table axis", description: "Select rotary table axis. Check the table direction on the machine and use the (Reversed) selection if the table is moving in the opposite direction.", group : "configuration", type : "enum", values : [ {title:"No rotary", id:"none"}, {title:"X", id:"x"}, {title:"Y", id:"y"}, {title:"Z", id:"z"}, {title:"X (Reversed)", id:"-x"}, {title:"Y (Reversed)", id:"-y"}, {title:"Z (Reversed)", id:"-z"} ], value: "none", scope: "post" } }; // wcs definiton wcsDefinitions = { useZeroOffset: false, wcs : [ {name:"Standard", format:"#", range:[1, 1]} ] }; var gFormat = createFormat({decimals:0}); var mFormat = createFormat({decimals:0}); var xyzFormat = createFormat({decimals:0}); var abcFormat = createFormat({decimals:0, scale:DEG}); var feedFormat = createFormat({decimals:1, type:FORMAT_REAL, minDigitsRight:1, scale:1 / 60}); var toolFormat = createFormat({decimals:0}); var rpmFormat = createFormat({decimals:0}); var milliFormat = createFormat({decimals:0}); // milliseconds var taperFormat = createFormat({decimals:1, scale:DEG}); var xOutput = createOutputVariable({onchange:function() {state.retractedX = false;}, suffix:",", control:CONTROL_FORCE}, xyzFormat); var yOutput = createOutputVariable({onchange:function() {state.retractedY = false;}, suffix:",", control:CONTROL_FORCE}, xyzFormat); var zOutput = createOutputVariable({onchange:function() {state.retractedZ = false;}, control:CONTROL_FORCE}, xyzFormat); var aOutput = createOutputVariable({prefix:"A"}, abcFormat); var bOutput = createOutputVariable({prefix:"B"}, abcFormat); var cOutput = createOutputVariable({prefix:"C"}, abcFormat); var feedOutput = createOutputVariable({prefix:"V"}, feedFormat); var sOutput = createOutputVariable({control:CONTROL_FORCE}, rpmFormat); var fourthAxisClamp = createOutputVariable({}, mFormat); var fifthAxisClamp = createOutputVariable({}, mFormat); var settings = { machineAngles: { // refer to https://cam.autodesk.com/posts/reference/classMachineConfiguration.html#a14bcc7550639c482492b4ad05b1580c8 controllingAxis: ABC, type : PREFER_PREFERENCE, options : ENABLE_ALL }, workPlaneMethod: { useTiltedWorkplane : false, // specifies that tilted workplanes should be used (ie. G68.2, G254, PLANE SPATIAL, CYCLE800), can be overwritten by property eulerConvention : EULER_ZXZ_R, // specifies the euler convention (ie EULER_XYZ_R), set to undefined to use machine angles for TWP commands ('undefined' requires machine configuration) eulerCalculationMethod: "standard", // ('standard' / 'machine') 'machine' adjusts euler angles to match the machines ABC orientation, machine configuration required cancelTiltFirst : false, // cancel tilted workplane prior to WCS (G54-G59) blocks forceMultiAxisIndexing: false, // force multi-axis indexing for 3D programs optimizeType : OPTIMIZE_AXIS // can be set to OPTIMIZE_NONE, OPTIMIZE_BOTH, OPTIMIZE_TABLES, OPTIMIZE_HEADS, OPTIMIZE_AXIS. 'undefined' uses legacy rotations }, comments: { permittedCommentChars: " abcdefghijklmnopqrstuvwxyz0123456789.,=_-", // letters are not case sensitive, use option 'outputFormat' below. Set to 'undefined' to allow any character prefix : "/ ", // specifies the prefix for the comment suffix : "", // specifies the suffix for the comment outputFormat : "upperCase", // can be set to "upperCase", "lowerCase" and "ignoreCase". Set to "ignoreCase" to write comments without upper/lower case formatting maximumLineLength : 0 // the maximum number of characters allowed in a line, set to 0 to disable comment output }, supportsOptionalBlocks : false, // specifies if optional block output is supported maximumToolNumber : 6, // specifies the maximum allowed tool number maximumToolLengthOffset : 6, // specifies the maximum allowed tool length offset number writeBlockSuffix : ";", // specifies the suffix to output for the writeBlock function at the end of each line // fixed settings below, do not modify supportsTCP : false, // this postprocessor does not support TCP supportsInverseTimeFeed : false, // this postprocessor does not support inverse time feedrates supportsRadiusCompensation: false // this postprocessor does not support tool radius compensation }; /** Compare a text string to acceptable choices. Returns -1 if there is no match. */ function parseChoice() { for (var i = 1; i < arguments.length; ++i) { if (String(arguments[0]).toUpperCase() == String(arguments[i]).toUpperCase()) { return i - 1; } } return -1; } function defineMachine() { var useTCP = false; if (getProperty("rotaryTableAxis") != "none") { if (receivedMachineConfiguration && machineConfiguration.isMultiAxisConfiguration()) { error(localize("You can only select either a machine in the CAM setup or use the properties to define your kinematics.")); } // Define rotary attributes from properties var rotary = parseChoice(getProperty("rotaryTableAxis"), "-Z", "-Y", "-X", "NONE", "X", "Y", "Z"); if (rotary < 0) { error(localize("Valid rotaryTableAxis values are: None, X, Y, Z, -X, -Y, -Z")); } rotary -= 3; // Define Master (carrier) axis var masterAxis = Math.abs(rotary) - 1; if (masterAxis >= 0) { var rotaryVector = [0, 0, 0]; rotaryVector[masterAxis] = rotary / Math.abs(rotary); var aAxis = createAxis({coordinate:0, table:true, axis:rotaryVector, cyclic:true, preference:0, tcp:useTCP, reset:3}); machineConfiguration = new MachineConfiguration(aAxis); } if (receivedMachineConfiguration) { warning(localize("The provided CAM machine configuration is overwritten by the postprocessor.")); receivedMachineConfiguration = false; // CAM provided machine configuration is overwritten } } if (!receivedMachineConfiguration) { switch (getProperty("machineModel")) { case "mdx-15/20": machineConfiguration.setHomePositionX(toPreciseUnit(0, MM)); machineConfiguration.setHomePositionY(toPreciseUnit(0, MM)); machineConfiguration.setRetractPlane(toPreciseUnit(4, MM)); machineConfiguration.setMinimumSpindleSpeed(6500); machineConfiguration.setMaximumSpindleSpeed(6500); break; case "mdx-40": machineConfiguration.setHomePositionX(toPreciseUnit(0, MM)); machineConfiguration.setHomePositionY(toPreciseUnit(0, MM)); machineConfiguration.setRetractPlane(toPreciseUnit(105, MM)); machineConfiguration.setMinimumSpindleSpeed(4500); machineConfiguration.setMaximumSpindleSpeed(15000); break; case "mdx-50": machineConfiguration.setHomePositionX(toPreciseUnit(0, MM)); machineConfiguration.setHomePositionY(toPreciseUnit(0, MM)); machineConfiguration.setRetractPlane(toPreciseUnit(135, MM)); machineConfiguration.setMinimumSpindleSpeed(4500); machineConfiguration.setMaximumSpindleSpeed(15000); break; case "mdx-540": machineConfiguration.setHomePositionX(toPreciseUnit(0, MM)); machineConfiguration.setHomePositionY(toPreciseUnit(0, MM)); machineConfiguration.setRetractPlane(toPreciseUnit(155, MM)); machineConfiguration.setMinimumSpindleSpeed(3000); machineConfiguration.setMaximumSpindleSpeed(12000); break; } machineConfiguration.setModel(getProperty("machineModel").toUpperCase()); machineConfiguration.setVendor("Roland DG"); // multiaxis settings if (machineConfiguration.isHeadConfiguration()) { machineConfiguration.setVirtualTooltip(false); // translate the pivot point to the virtual tool tip for nonTCP rotary heads } // retract / reconfigure var performRewinds = false; // set to true to enable the rewind/reconfigure logic if (performRewinds) { machineConfiguration.enableMachineRewinds(); // enables the retract/reconfigure logic safeRetractDistance = (unit == IN) ? 1 : 25; // additional distance to retract out of stock, can be overridden with a property safeRetractFeed = (unit == IN) ? 20 : 500; // retract feed rate safePlungeFeed = (unit == IN) ? 10 : 250; // plunge feed rate machineConfiguration.setSafeRetractDistance(safeRetractDistance); machineConfiguration.setSafeRetractFeedrate(safeRetractFeed); machineConfiguration.setSafePlungeFeedrate(safePlungeFeed); var stockExpansion = new Vector(toPreciseUnit(0.1, IN), toPreciseUnit(0.1, IN), toPreciseUnit(0.1, IN)); // expand stock XYZ values machineConfiguration.setRewindStockExpansion(stockExpansion); } // multi-axis feedrates if (machineConfiguration.isMultiAxisConfiguration()) { machineConfiguration.setMultiAxisFeedrate( FEED_FPM, 99999.9999, // maximum output value for inverse time feed rates INVERSE_MINUTES, // INVERSE_MINUTES/INVERSE_SECONDS or DPM_COMBINATION/DPM_STANDARD 0.5, // tolerance to determine when the DPM feed has changed 1.0 // ratio of rotary accuracy to linear accuracy for DPM calculations ); setMachineConfiguration(machineConfiguration); } /* home positions */ // machineConfiguration.setHomePositionX(toPreciseUnit(0, IN)); // machineConfiguration.setHomePositionY(toPreciseUnit(0, IN)); // machineConfiguration.setRetractPlane(toPreciseUnit(0, IN)); } } function onOpen() { // define and enable machine configuration receivedMachineConfiguration = machineConfiguration.isReceived(); if (typeof defineMachine == "function") { defineMachine(); // hardcoded machine configuration } activateMachine(); // enable the machine optimizations and settings if (!getProperty("separateWordsWithSpace")) { setWordSeparator(""); } writeBlock(";;" + (getProperty("machineModel") == "mdx-15/20" ? "^IN" : "^DF")); switch (getProperty("machineModel")) { case "mdx-15/20": highFeedrate = (unit == MM) ? 900 : 35; step = 0.025; break; case "mdx-40": highFeedrate = (unit == MM) ? 3000 : 118; step = 0.01; break; case "mdx-50": highFeedrate = (unit == MM) ? 3600 : 141; step = 0.01; break; case "mdx-540": highFeedrate = (unit == MM) ? 7500 : 295; step = 0.01; break; default: error(localize("No machine type is selected. You have to define a machine type using the properties.")); } var scale = 1 / step; xOutput.setScale(scale); yOutput.setScale(scale); zOutput.setScale(scale); writeBlock(getProperty("machineModel") == "mdx-15/20" ? "!MC1" : "!MC0;" + feedOutput.format(highFeedrate)); validateCommonParameters(); } function getSpindleSpeed() { var rpm = spindleSpeed; var speedCode = 0; var sDiff = machineConfiguration.getMaximumSpindleSpeed() - machineConfiguration.getMinimumSpindleSpeed(); var checkrpm = machineConfiguration.getMinimumSpindleSpeed(); var middle = machineConfiguration.getMinimumSpindleSpeed(); while (checkrpm < rpm) { // find the closest speedCode speedCode += 1; var nextSpindleSpeed = ((sDiff / 15) * speedCode) + machineConfiguration.getMinimumSpindleSpeed(); middle = (nextSpindleSpeed - checkrpm) / 2; checkrpm += (nextSpindleSpeed - checkrpm); } if ((rpm + middle) < checkrpm) { // find the middle of spindle speed range speedCode -= 1; } return speedCode; } function positionABC(abc, force) { if (!machineConfiguration.isMultiAxisConfiguration()) { error("Function 'positionABC' can only be used with multi-axis machine configurations."); } if (force) { forceABC(); } var a = aOutput.format(abc.x); var b = bOutput.format(abc.y); var c = cOutput.format(abc.z); if (a || b || c) { writeRetract(); onCommand(COMMAND_UNLOCK_MULTI_AXIS); writeBlock("!ZE ", a, b, c); setCurrentABC(abc); // required for machine simulation machineSimulation({a:abc.x, b:abc.y, c:abc.z, coordinates:MACHINE}); } } function onSection() { var forceSectionRestart = optionalSection && !currentSection.isOptional(); optionalSection = currentSection.isOptional(); var insertToolCall = isToolChangeNeeded("number") || forceSectionRestart; var newWorkOffset = isNewWorkOffset() || forceSectionRestart; var newWorkPlane = isNewWorkPlane() || forceSectionRestart; if (insertToolCall || newWorkOffset || newWorkPlane) { writeRetract(); //retract } writeComment(getParameter("operation-comment", "")); writeToolCall(tool, insertToolCall); startSpindle(tool, insertToolCall); var abc = defineWorkPlane(currentSection, true); forceXYZ(); forceFeed(); // prepositioning var initialPosition = getFramePosition(currentSection.getInitialPosition()); if (insertToolCall) { writeBlock("Z", xOutput.format(initialPosition.x), yOutput.format(initialPosition.y), zOutput.format(initialPosition.z)); } } function onDwell(seconds) { var maxValue = 32.767; if (seconds > maxValue) { warning(subst(localize("Dwelling time of '%1' exceeds the maximum value of '%2' in operation '%3'"), seconds, maxValue, getParameter("operation-comment", ""))); } milliseconds = clamp(1, seconds * 1000, 32767); writeBlock("W", milliFormat.format(milliseconds)); } function onRapid(_x, _y, _z) { invokeOnLinear(_x, _y, _z, highFeedrate); forceFeed(); } function onLinear(_x, _y, _z, feed) { var x = xOutput.format(_x); var y = yOutput.format(_y); var z = zOutput.format(_z); var f = feedOutput.format(feed); if (f) { writeBlock(f); } if (x || y || z) { writeBlock("Z", x, y, z); } } function onCircular() { linearize(tolerance); // note: could use operation tolerance } function onSpindleSpeed() { writeBlock( "!RC", (getProperty("spindleSpeedInRPM") ? sOutput.format(spindleSpeed) : getSpindleSpeed()) + ";", "!MC1" // spindle on (M03)) ); } function onCommand(command) { switch (command) { case COMMAND_COOLANT_OFF: return; case COMMAND_COOLANT_ON: return; case COMMAND_STOP: return; case COMMAND_START_SPINDLE: forceSpindleSpeed = false; if (spindleSpeed < machineConfiguration.getMinimumSpindleSpeed() || spindleSpeed > machineConfiguration.getMaximumSpindleSpeed()) { error(subst( localize("Spindle speed is out of range for operation \"%1\"."), getParameter("operation-comment", "")) + " " + subst(localize("The spindle speed has to be between %1 and %2 RPM."), rpmFormat.format(machineConfiguration.getMinimumSpindleSpeed()), rpmFormat.format(machineConfiguration.getMaximumSpindleSpeed()))); } writeBlock( "!RC", (getProperty("spindleSpeedInRPM") ? sOutput.format(spindleSpeed) : getSpindleSpeed()) + ";", "!MC1" // spindle on (M03)) ); return; case COMMAND_LOAD_TOOL: if (getProperty("useToolCall")) { writeBlock("J" + toolFormat.format(tool.number)); } else { if (!isFirstSection()) { error(localize("Tool change is not supported without ATC. Please only post operations using the same tool.")); } } return; case COMMAND_LOCK_MULTI_AXIS: if (machineConfiguration.isMultiAxisConfiguration()) { // writeBlock(fourthAxisClamp.format(25)); // lock 4th axis if (machineConfiguration.getNumberOfAxes() > 4) { // writeBlock(fifthAxisClamp.format(35)); // lock 5th axis } } return; case COMMAND_UNLOCK_MULTI_AXIS: if (machineConfiguration.isMultiAxisConfiguration()) { // writeBlock(fourthAxisClamp.format(26)); // unlock 4th axis if (machineConfiguration.getNumberOfAxes() > 4) { // writeBlock(fifthAxisClamp.format(36)); // unlock 5th axis } } return; case COMMAND_STOP_SPINDLE: writeBlock("!MC0"); return; case COMMAND_SPINDLE_CLOCKWISE: return; case COMMAND_SPINDLE_COUNTERCLOCKWISE: return; case COMMAND_BREAK_CONTROL: return; } onUnsupportedCommand(command); } function onSectionEnd() { if (!isLastSection()) { if (tool.breakControl && isToolChangeNeeded(getNextSection(), getProperty("toolAsName") ? "description" : "number")) { onCommand(COMMAND_BREAK_CONTROL); } } } function writeRetract() { if (!state.retractedX || !state.retractedY || !state.retractedZ) { forceFeed(); var _xHome = machineConfiguration.hasHomePositionX() ? machineConfiguration.getHomePositionX() : toPreciseUnit(0, MM); var _yHome = machineConfiguration.hasHomePositionY() ? machineConfiguration.getHomePositionY() : toPreciseUnit(0, MM); var _zHome = machineConfiguration.getRetractPlane() != 0 ? machineConfiguration.getRetractPlane() : toPreciseUnit(0, MM); writeBlock("^PR"); writeBlock(feedOutput.format(highFeedrate)); writeBlock("Z", xOutput.format(_xHome), yOutput.format(_yHome), zOutput.format(_zHome)); // retract writeBlock("^PA"); forceXYZ(); } state.retractedX = state.retractedY = state.retractedZ = true; } function onClose() { onCommand(COMMAND_STOP_SPINDLE); writeRetract(); writeBlock((getProperty("machineModel") == "mdx-15/20") ? "^IN" : "^DF"); } // >>>>> INCLUDED FROM include_files/commonFunctions.cpi // internal variables, do not change var receivedMachineConfiguration; var tcp = {isSupportedByControl:getSetting("supportsTCP", true), isSupportedByMachine:false, isSupportedByOperation:false}; var state = { retractedX : false, // specifies that the machine has been retracted in X retractedY : false, // specifies that the machine has been retracted in Y retractedZ : false, // specifies that the machine has been retracted in Z tcpIsActive : false, // specifies that TCP is currently active twpIsActive : false, // specifies that TWP is currently active lengthCompensationActive: !getSetting("outputToolLengthCompensation", true), // specifies that tool length compensation is active mainState : true // specifies the current context of the state (true = main, false = optional) }; var validateLengthCompensation = getSetting("outputToolLengthCompensation", true); // disable validation when outputToolLengthCompensation is disabled var multiAxisFeedrate; var sequenceNumber; var optionalSection = false; var currentWorkOffset; var forceSpindleSpeed = false; var operationNeedsSafeStart = false; // used to convert blocks to optional for safeStartAllOperations function activateMachine() { // disable unsupported rotary axes output if (!machineConfiguration.isMachineCoordinate(0) && (typeof aOutput != "undefined")) { aOutput.disable(); } if (!machineConfiguration.isMachineCoordinate(1) && (typeof bOutput != "undefined")) { bOutput.disable(); } if (!machineConfiguration.isMachineCoordinate(2) && (typeof cOutput != "undefined")) { cOutput.disable(); } // setup usage of useTiltedWorkplane settings.workPlaneMethod.useTiltedWorkplane = getProperty("useTiltedWorkplane") != undefined ? getProperty("useTiltedWorkplane") : getSetting("workPlaneMethod.useTiltedWorkplane", false); settings.workPlaneMethod.useABCPrepositioning = getSetting("workPlaneMethod.useABCPrepositioning", true); if (!machineConfiguration.isMultiAxisConfiguration()) { return; // don't need to modify any settings for 3-axis machines } // identify if any of the rotary axes has TCP enabled var axes = [machineConfiguration.getAxisU(), machineConfiguration.getAxisV(), machineConfiguration.getAxisW()]; tcp.isSupportedByMachine = axes.some(function(axis) {return axis.isEnabled() && axis.isTCPEnabled();}); // true if TCP is enabled on any rotary axis // save multi-axis feedrate settings from machine configuration var mode = machineConfiguration.getMultiAxisFeedrateMode(); var type = mode == FEED_INVERSE_TIME ? machineConfiguration.getMultiAxisFeedrateInverseTimeUnits() : (mode == FEED_DPM ? machineConfiguration.getMultiAxisFeedrateDPMType() : DPM_STANDARD); multiAxisFeedrate = { mode : mode, maximum : machineConfiguration.getMultiAxisFeedrateMaximum(), type : type, tolerance: mode == FEED_DPM ? machineConfiguration.getMultiAxisFeedrateOutputTolerance() : 0, bpwRatio : mode == FEED_DPM ? machineConfiguration.getMultiAxisFeedrateBpwRatio() : 1 }; // setup of retract/reconfigure TAG: Only needed until post kernel supports these machine config settings if (receivedMachineConfiguration && machineConfiguration.performRewinds()) { safeRetractDistance = machineConfiguration.getSafeRetractDistance(); safePlungeFeed = machineConfiguration.getSafePlungeFeedrate(); safeRetractFeed = machineConfiguration.getSafeRetractFeedrate(); } if (typeof safeRetractDistance == "number" && getProperty("safeRetractDistance") != undefined && getProperty("safeRetractDistance") != 0) { safeRetractDistance = getProperty("safeRetractDistance"); } if (revision >= 50294) { activateAutoPolarMode({tolerance:tolerance / 2, optimizeType:OPTIMIZE_AXIS, expandCycles:getSetting("polarCycleExpandMode", EXPAND_ALL)}); } if (machineConfiguration.isHeadConfiguration() && getSetting("workPlaneMethod.compensateToolLength", false)) { for (var i = 0; i < getNumberOfSections(); ++i) { var section = getSection(i); if (section.isMultiAxis()) { machineConfiguration.setToolLength(getBodyLength(section.getTool())); // define the tool length for head adjustments section.optimizeMachineAnglesByMachine(machineConfiguration, OPTIMIZE_AXIS); } } } else { optimizeMachineAngles2(OPTIMIZE_AXIS); } } function getBodyLength(tool) { for (var i = 0; i < getNumberOfSections(); ++i) { var section = getSection(i); if (tool.number == section.getTool().number) { if (section.hasParameter("operation:tool_assemblyGaugeLength")) { // For Fusion return section.getParameter("operation:tool_assemblyGaugeLength", tool.bodyLength + tool.holderLength); } else { // Legacy products return section.getParameter("operation:tool_overallLength", tool.bodyLength + tool.holderLength); } } } return tool.bodyLength + tool.holderLength; } function getFeed(f) { if (getProperty("useG95")) { return feedOutput.format(f / spindleSpeed); // use feed value } if (typeof activeMovements != "undefined" && 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 settings.parametricFeeds.feedOutputVariable + (settings.parametricFeeds.firstFeedParameter + feedContext.id); } } currentFeedId = undefined; // force parametric feed next time } return feedOutput.format(f); // use feed value } function validateCommonParameters() { validateToolData(); for (var i = 0; i < getNumberOfSections(); ++i) { var section = getSection(i); if (getSection(0).workOffset == 0 && section.workOffset > 0) { if (!(typeof wcsDefinitions != "undefined" && wcsDefinitions.useZeroOffset)) { error(localize("Using multiple work offsets is not possible if the initial work offset is 0.")); } } if (section.isMultiAxis()) { if (!section.isOptimizedForMachine() && (!getSetting("workPlaneMethod.useTiltedWorkplane", false) || !getSetting("supportsToolVectorOutput", false))) { error(localize("This postprocessor requires a machine configuration for 5-axis simultaneous toolpath.")); } if (machineConfiguration.getMultiAxisFeedrateMode() == FEED_INVERSE_TIME && !getSetting("supportsInverseTimeFeed", true)) { error(localize("This postprocessor does not support inverse time feedrates.")); } if (getSetting("supportsToolVectorOutput", false) && !tcp.isSupportedByControl) { error(localize("Incompatible postprocessor settings detected." + EOL + "Setting 'supportsToolVectorOutput' requires setting 'supportsTCP' to be enabled as well.")); } } } if (!tcp.isSupportedByControl && tcp.isSupportedByMachine) { error(localize("The machine configuration has TCP enabled which is not supported by this postprocessor.")); } if (getProperty("safePositionMethod") == "clearanceHeight") { var msg = "-Attention- Property 'Safe Retracts' is set to 'Clearance Height'." + EOL + "Ensure the clearance height will clear the part and or fixtures." + EOL + "Raise the Z-axis to a safe height before starting the program."; warning(msg); writeComment(msg); } } function validateToolData() { var _default = 99999; var _maximumSpindleRPM = machineConfiguration.getMaximumSpindleSpeed() > 0 ? machineConfiguration.getMaximumSpindleSpeed() : settings.maximumSpindleRPM == undefined ? _default : settings.maximumSpindleRPM; var _maximumToolNumber = machineConfiguration.isReceived() && machineConfiguration.getNumberOfTools() > 0 ? machineConfiguration.getNumberOfTools() : settings.maximumToolNumber == undefined ? _default : settings.maximumToolNumber; var _maximumToolLengthOffset = settings.maximumToolLengthOffset == undefined ? _default : settings.maximumToolLengthOffset; var _maximumToolDiameterOffset = settings.maximumToolDiameterOffset == undefined ? _default : settings.maximumToolDiameterOffset; var header = ["Detected maximum values are out of range.", "Maximum values:"]; var warnings = { toolNumber : {msg:"Tool number value exceeds the maximum value for tool: " + EOL, max:" Tool number: " + _maximumToolNumber, values:[]}, lengthOffset : {msg:"Tool length offset value exceeds the maximum value for tool: " + EOL, max:" Tool length offset: " + _maximumToolLengthOffset, values:[]}, diameterOffset: {msg:"Tool diameter offset value exceeds the maximum value for tool: " + EOL, max:" Tool diameter offset: " + _maximumToolDiameterOffset, values:[]}, spindleSpeed : {msg:"Spindle speed exceeds the maximum value for operation: " + EOL, max:" Spindle speed: " + _maximumSpindleRPM, values:[]} }; var toolIds = []; for (var i = 0; i < getNumberOfSections(); ++i) { var section = getSection(i); if (toolIds.indexOf(section.getTool().getToolId()) === -1) { // loops only through sections which have a different tool ID var toolNumber = section.getTool().number; var lengthOffset = section.getTool().lengthOffset; var diameterOffset = section.getTool().diameterOffset; var comment = section.getParameter("operation-comment", ""); if (toolNumber > _maximumToolNumber && !getProperty("toolAsName")) { warnings.toolNumber.values.push(SP + toolNumber + EOL); } if (lengthOffset > _maximumToolLengthOffset) { warnings.lengthOffset.values.push(SP + "Tool " + toolNumber + " (" + comment + "," + " Length offset: " + lengthOffset + ")" + EOL); } if (diameterOffset > _maximumToolDiameterOffset) { warnings.diameterOffset.values.push(SP + "Tool " + toolNumber + " (" + comment + "," + " Diameter offset: " + diameterOffset + ")" + EOL); } toolIds.push(section.getTool().getToolId()); } // loop through all sections regardless of tool id for idenitfying spindle speeds // identify if movement ramp is used in current toolpath, use ramp spindle speed for comparisons var ramp = section.getMovements() & ((1 << MOVEMENT_RAMP) | (1 << MOVEMENT_RAMP_ZIG_ZAG) | (1 << MOVEMENT_RAMP_PROFILE) | (1 << MOVEMENT_RAMP_HELIX)); var _sectionSpindleSpeed = Math.max(section.getTool().spindleRPM, ramp ? section.getTool().rampingSpindleRPM : 0, 0); if (_sectionSpindleSpeed > _maximumSpindleRPM) { warnings.spindleSpeed.values.push(SP + section.getParameter("operation-comment", "") + " (" + _sectionSpindleSpeed + " RPM" + ")" + EOL); } } // sort lists by tool number warnings.toolNumber.values.sort(function(a, b) {return a - b;}); warnings.lengthOffset.values.sort(function(a, b) {return a.localeCompare(b);}); warnings.diameterOffset.values.sort(function(a, b) {return a.localeCompare(b);}); var warningMessages = []; for (var key in warnings) { if (warnings[key].values != "") { header.push(warnings[key].max); // add affected max values to the header warningMessages.push(warnings[key].msg + warnings[key].values.join("")); } } if (warningMessages.length != 0) { warningMessages.unshift(header.join(EOL) + EOL); warning(warningMessages.join(EOL)); } } function forceFeed() { currentFeedId = undefined; feedOutput.reset(); } /** 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(); forceFeed(); } /** Writes the specified block. */ function writeBlock() { var text = formatWords(arguments); if (!text) { return; } var prefix = getSetting("sequenceNumberPrefix", "N"); var suffix = getSetting("writeBlockSuffix", ""); if ((optionalSection || skipBlocks) && !getSetting("supportsOptionalBlocks", true)) { error(localize("Optional blocks are not supported by this post.")); } if (getProperty("showSequenceNumbers") == "true") { if (sequenceNumber == undefined || sequenceNumber >= settings.maximumSequenceNumber) { sequenceNumber = getProperty("sequenceNumberStart"); } if (optionalSection || skipBlocks) { writeWords2("/", prefix + sequenceNumber, text + suffix); } else { writeWords2(prefix + sequenceNumber, text + suffix); } sequenceNumber += getProperty("sequenceNumberIncrement"); } else { if (optionalSection || skipBlocks) { writeWords2("/", text + suffix); } else { writeWords(text + suffix); } } } validate(settings.comments, "Setting 'comments' is required but not defined."); function formatComment(text) { var prefix = settings.comments.prefix; var suffix = settings.comments.suffix; var _permittedCommentChars = settings.comments.permittedCommentChars == undefined ? "" : settings.comments.permittedCommentChars; switch (settings.comments.outputFormat) { case "upperCase": text = text.toUpperCase(); _permittedCommentChars = _permittedCommentChars.toUpperCase(); break; case "lowerCase": text = text.toLowerCase(); _permittedCommentChars = _permittedCommentChars.toLowerCase(); break; case "ignoreCase": _permittedCommentChars = _permittedCommentChars.toUpperCase() + _permittedCommentChars.toLowerCase(); break; default: error(localize("Unsupported option specified for setting 'comments.outputFormat'.")); } if (_permittedCommentChars != "") { text = filterText(String(text), _permittedCommentChars); } text = String(text).substring(0, settings.comments.maximumLineLength - prefix.length - suffix.length); return text != "" ? prefix + text + suffix : ""; } /** Output a comment. */ function writeComment(text) { if (!text) { return; } var comments = String(text).split(EOL); for (comment in comments) { var _comment = formatComment(comments[comment]); if (_comment) { if (getSetting("comments.showSequenceNumbers", false)) { writeBlock(_comment); } else { writeln(_comment); } } } } function onComment(text) { writeComment(text); } /** Writes the specified block - used for tool changes only. */ function writeToolBlock() { var show = getProperty("showSequenceNumbers"); setProperty("showSequenceNumbers", (show == "true" || show == "toolChange") ? "true" : "false"); writeBlock(arguments); setProperty("showSequenceNumbers", show); machineSimulation({/*x:toPreciseUnit(200, MM), y:toPreciseUnit(200, MM), coordinates:MACHINE,*/ mode:TOOLCHANGE}); // move machineSimulation to a tool change position } var skipBlocks = false; var initialState = JSON.parse(JSON.stringify(state)); // save initial state var optionalState = JSON.parse(JSON.stringify(state)); var saveCurrentSectionId = undefined; function writeStartBlocks(isRequired, code) { var saveSkipBlocks = skipBlocks; var saveMainState = state; // save main state if (!isRequired) { if (!getProperty("safeStartAllOperations", false)) { return; // when safeStartAllOperations is disabled, dont output code and return } if (saveCurrentSectionId != getCurrentSectionId()) { saveCurrentSectionId = getCurrentSectionId(); forceModals(); // force all modal variables when entering a new section optionalState = Object.create(initialState); // reset optionalState to initialState when entering a new section } skipBlocks = true; // if values are not required, but safeStartAllOperations is enabled - write following blocks as optional state = optionalState; // set state to optionalState if skipBlocks is true state.mainState = false; } code(); // writes out the code which is passed to this function as an argument state = saveMainState; // restore main state skipBlocks = saveSkipBlocks; // restore skipBlocks value } var pendingRadiusCompensation = -1; function onRadiusCompensation() { pendingRadiusCompensation = radiusCompensation; if (pendingRadiusCompensation >= 0 && !getSetting("supportsRadiusCompensation", true)) { error(localize("Radius compensation mode is not supported.")); return; } } function onPassThrough(text) { var commands = String(text).split(","); for (text in commands) { writeBlock(commands[text]); } } function forceModals() { if (arguments.length == 0) { // reset all modal variables listed below if (typeof gMotionModal != "undefined") { gMotionModal.reset(); } if (typeof gPlaneModal != "undefined") { gPlaneModal.reset(); } if (typeof gAbsIncModal != "undefined") { gAbsIncModal.reset(); } if (typeof gFeedModeModal != "undefined") { gFeedModeModal.reset(); } } else { for (var i in arguments) { arguments[i].reset(); // only reset the modal variable passed to this function } } } /** Helper function to be able to use a default value for settings which do not exist. */ function getSetting(setting, defaultValue) { var result = defaultValue; var keys = setting.split("."); var obj = settings; for (var i in keys) { if (obj[keys[i]] != undefined) { // setting does exist result = obj[keys[i]]; if (typeof [keys[i]] === "object") { obj = obj[keys[i]]; continue; } } else { // setting does not exist, use default value if (defaultValue != undefined) { result = defaultValue; } else { error("Setting '" + keys[i] + "' has no default value and/or does not exist."); return undefined; } } } return result; } function getForwardDirection(_section) { var forward = undefined; var _optimizeType = settings.workPlaneMethod && settings.workPlaneMethod.optimizeType; if (_section.isMultiAxis()) { forward = _section.workPlane.forward; } else if (!getSetting("workPlaneMethod.useTiltedWorkplane", false) && machineConfiguration.isMultiAxisConfiguration()) { if (_optimizeType == undefined) { var saveRotation = getRotation(); getWorkPlaneMachineABC(_section, true); forward = getRotation().forward; setRotation(saveRotation); // reset rotation } else { var abc = getWorkPlaneMachineABC(_section, false); var forceAdjustment = settings.workPlaneMethod.optimizeType == OPTIMIZE_TABLES || settings.workPlaneMethod.optimizeType == OPTIMIZE_BOTH; forward = machineConfiguration.getOptimizedDirection(_section.workPlane.forward, abc, false, forceAdjustment); } } else { forward = getRotation().forward; } return forward; } function getRetractParameters() { var _arguments = typeof arguments[0] === "object" ? arguments[0].axes : arguments; var singleLine = arguments[0].singleLine == undefined ? true : arguments[0].singleLine; var words = []; // store all retracted axes in an array var retractAxes = new Array(false, false, false); var method = getProperty("safePositionMethod", "undefined"); 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 undefined; } validate(settings.retract, "Setting 'retract' is required but not defined."); validate(_arguments.length != 0, "No axis specified for getRetractParameters()."); for (i in _arguments) { retractAxes[_arguments[i]] = true; } if ((retractAxes[0] || retractAxes[1]) && !state.retractedZ) { // retract Z first before moving to X/Y home error(localize("Retracting in X/Y is not possible without being retracted in Z.")); return undefined; } // special conditions if (retractAxes[0] || retractAxes[1]) { method = getSetting("retract.methodXY", method); } if (retractAxes[2]) { method = getSetting("retract.methodZ", method); } // define home positions var useZeroValues = (settings.retract.useZeroValues && settings.retract.useZeroValues.indexOf(method) != -1); var _xHome = machineConfiguration.hasHomePositionX() && !useZeroValues ? machineConfiguration.getHomePositionX() : toPreciseUnit(0, MM); var _yHome = machineConfiguration.hasHomePositionY() && !useZeroValues ? machineConfiguration.getHomePositionY() : toPreciseUnit(0, MM); var _zHome = machineConfiguration.getRetractPlane() != 0 && !useZeroValues ? machineConfiguration.getRetractPlane() : toPreciseUnit(0, MM); for (var i = 0; i < _arguments.length; ++i) { switch (_arguments[i]) { case X: if (!state.retractedX) { words.push("X" + xyzFormat.format(_xHome)); xOutput.reset(); state.retractedX = true; } break; case Y: if (!state.retractedY) { words.push("Y" + xyzFormat.format(_yHome)); yOutput.reset(); state.retractedY = true; } break; case Z: if (!state.retractedZ) { words.push("Z" + xyzFormat.format(_zHome)); zOutput.reset(); state.retractedZ = true; } break; default: error(localize("Unsupported axis specified for getRetractParameters().")); return undefined; } } return { method : method, retractAxes: retractAxes, words : words, positions : { x: retractAxes[0] ? _xHome : undefined, y: retractAxes[1] ? _yHome : undefined, z: retractAxes[2] ? _zHome : undefined}, singleLine: singleLine}; } /** Returns true when subprogram logic does exist into the post. */ function subprogramsAreSupported() { return typeof subprogramState != "undefined"; } // Start of machine simulation connection move support var debugSimulation = false; // enable to output debug information for connection move support in the NC program var TCPON = "TCP ON"; var TCPOFF = "TCP OFF"; var TWPON = "TWP ON"; var TWPOFF = "TWP OFF"; var TOOLCHANGE = "TOOL CHANGE"; var RETRACTTOOLAXIS = "RETRACT TOOLAXIS"; var WORK = "WORK CS"; var MACHINE = "MACHINE CS"; var MIN = "MIN"; var MAX = "MAX"; var WARNING_NON_RANGE = [0, 1, 2]; var isTwpOn; var isTcpOn; /** * Helper function for connection moves in machine simulation. * @param {Object} parameters An object containing the desired options for machine simulation. * @note Available properties are: * @param {Number} x X axis position, alternatively use MIN or MAX to move to the axis limit * @param {Number} y Y axis position, alternatively use MIN or MAX to move to the axis limit * @param {Number} z Z axis position, alternatively use MIN or MAX to move to the axis limit * @param {Number} a A axis position (in radians) * @param {Number} b B axis position (in radians) * @param {Number} c C axis position (in radians) * @param {Number} feed desired feedrate, automatically set to high/current feedrate if not specified * @param {String} mode mode TCPON | TCPOFF | TWPON | TWPOFF | TOOLCHANGE | RETRACTTOOLAXIS * @param {String} coordinates WORK | MACHINE - if undefined, work coordinates will be used by default * @param {Number} eulerAngles the calculated Euler angles for the workplane * @example machineSimulation({a:abc.x, b:abc.y, c:abc.z, coordinates:MACHINE}); machineSimulation({x:toPreciseUnit(200, MM), y:toPreciseUnit(200, MM), coordinates:MACHINE, mode:TOOLCHANGE}); */ function machineSimulation(parameters) { if (revision < 50198 || skipBlocks) { return; // return when post kernel revision is lower than 50198 or when skipBlocks is enabled } getAxisLimit = function(axis, limit) { validate(limit == MIN || limit == MAX, subst(localize("Invalid argument \"%1\" passed to the machineSimulation function."), limit)); var range = axis.getRange(); if (range.isNonRange()) { var axisLetters = ["X", "Y", "Z"]; var warningMessage = subst(localize("An attempt was made to move the \"%1\" axis to its MIN/MAX limits during machine simulation, but its range is set to \"unlimited\"." + EOL + "A limited range must be set for the \"%1\" axis in the machine definition, or these motions will not be shown in machine simulation."), axisLetters[axis.getCoordinate()]); warningOnce(warningMessage, WARNING_NON_RANGE[axis.getCoordinate()]); return undefined; } return limit == MIN ? range.minimum : range.maximum; }; var x = (isNaN(parameters.x) && parameters.x) ? getAxisLimit(machineConfiguration.getAxisX(), parameters.x) : parameters.x; var y = (isNaN(parameters.y) && parameters.y) ? getAxisLimit(machineConfiguration.getAxisY(), parameters.y) : parameters.y; var z = (isNaN(parameters.z) && parameters.z) ? getAxisLimit(machineConfiguration.getAxisZ(), parameters.z) : parameters.z; var rotaryAxesErrorMessage = localize("Invalid argument for rotary axes passed to the machineSimulation function. Only numerical values are supported."); var a = (isNaN(parameters.a) && parameters.a) ? error(rotaryAxesErrorMessage) : parameters.a; var b = (isNaN(parameters.b) && parameters.b) ? error(rotaryAxesErrorMessage) : parameters.b; var c = (isNaN(parameters.c) && parameters.c) ? error(rotaryAxesErrorMessage) : parameters.c; var coordinates = parameters.coordinates; var eulerAngles = parameters.eulerAngles; var feed = parameters.feed; if (feed === undefined && typeof gMotionModal !== "undefined") { feed = gMotionModal.getCurrent() !== 0; } var mode = parameters.mode; var performToolChange = mode == TOOLCHANGE; if (mode !== undefined && ![TCPON, TCPOFF, TWPON, TWPOFF, TOOLCHANGE, RETRACTTOOLAXIS].includes(mode)) { error(subst("Mode '%1' is not supported.", mode)); } // mode takes precedence over TCP/TWP states var enableTCP = isTcpOn; var enableTWP = isTwpOn; if (mode === TCPON || mode === TCPOFF) { enableTCP = mode === TCPON; } else if (mode === TWPON || mode === TWPOFF) { enableTWP = mode === TWPON; } else { enableTCP = typeof state !== "undefined" && state.tcpIsActive; enableTWP = typeof state !== "undefined" && state.twpIsActive; } var disableTCP = !enableTCP; var disableTWP = !enableTWP; if (disableTWP) { simulation.setTWPModeOff(); isTwpOn = false; } if (disableTCP) { simulation.setTCPModeOff(); isTcpOn = false; } if (enableTCP) { simulation.setTCPModeOn(); isTcpOn = true; } if (enableTWP) { if (settings.workPlaneMethod.eulerConvention == undefined) { simulation.setTWPModeAlignToCurrentPose(); } else if (eulerAngles) { simulation.setTWPModeByEulerAngles(settings.workPlaneMethod.eulerConvention, eulerAngles.x, eulerAngles.y, eulerAngles.z); } isTwpOn = true; } if (mode == RETRACTTOOLAXIS) { simulation.retractAlongToolAxisToLimit(); } if (debugSimulation) { writeln(" DEBUG" + JSON.stringify(parameters)); writeln(" DEBUG" + JSON.stringify({isTwpOn:isTwpOn, isTcpOn:isTcpOn, feed:feed})); } if (x !== undefined || y !== undefined || z !== undefined || a !== undefined || b !== undefined || c !== undefined) { if (x !== undefined) {simulation.setTargetX(x);} if (y !== undefined) {simulation.setTargetY(y);} if (z !== undefined) {simulation.setTargetZ(z);} if (a !== undefined) {simulation.setTargetA(a);} if (b !== undefined) {simulation.setTargetB(b);} if (c !== undefined) {simulation.setTargetC(c);} if (feed != undefined && feed) { simulation.setMotionToLinear(); simulation.setFeedrate(typeof feed == "number" ? feed : feedOutput.getCurrent() == 0 ? highFeedrate : feedOutput.getCurrent()); } else { simulation.setMotionToRapid(); } if (coordinates != undefined && coordinates == MACHINE) { simulation.moveToTargetInMachineCoords(); } else { simulation.moveToTargetInWorkCoords(); } } if (performToolChange) { simulation.performToolChangeCycle(); simulation.moveToTargetInMachineCoords(); } } // <<<<< INCLUDED FROM include_files/commonFunctions.cpi // >>>>> INCLUDED FROM include_files/defineWorkPlane.cpi validate(settings.workPlaneMethod, "Setting 'workPlaneMethod' is required but not defined."); function defineWorkPlane(_section, _setWorkPlane) { var abc = new Vector(0, 0, 0); if (settings.workPlaneMethod.forceMultiAxisIndexing || !is3D() || machineConfiguration.isMultiAxisConfiguration()) { if (isPolarModeActive()) { abc = getCurrentDirection(); } else if (_section.isMultiAxis()) { forceWorkPlane(); cancelTransformation(); abc = _section.isOptimizedForMachine() ? _section.getInitialToolAxisABC() : _section.getGlobalInitialToolAxis(); } else if (settings.workPlaneMethod.useTiltedWorkplane && settings.workPlaneMethod.eulerConvention != undefined) { if (settings.workPlaneMethod.eulerCalculationMethod == "machine" && machineConfiguration.isMultiAxisConfiguration()) { abc = machineConfiguration.getOrientation(getWorkPlaneMachineABC(_section, true)).getEuler2(settings.workPlaneMethod.eulerConvention); } else { abc = _section.workPlane.getEuler2(settings.workPlaneMethod.eulerConvention); } } else { abc = getWorkPlaneMachineABC(_section, true); } if (_setWorkPlane) { if (_section.isMultiAxis() || isPolarModeActive()) { // 4-5x simultaneous operations cancelWorkPlane(); if (_section.isOptimizedForMachine()) { positionABC(abc, true); } else { setCurrentDirection(abc); } } else { // 3x and/or 3+2x operations setWorkPlane(abc); } } } else { var remaining = _section.workPlane; if (!isSameDirection(remaining.forward, new Vector(0, 0, 1))) { error(localize("Tool orientation is not supported.")); return abc; } setRotation(remaining); } tcp.isSupportedByOperation = isTCPSupportedByOperation(_section); return abc; } function isTCPSupportedByOperation(_section) { var _tcp = _section.getOptimizedTCPMode() == OPTIMIZE_NONE; if (!_section.isMultiAxis() && (settings.workPlaneMethod.useTiltedWorkplane || (machineConfiguration.isMultiAxisConfiguration() && settings.workPlaneMethod.optimizeType != undefined ? getWorkPlaneMachineABC(_section, false).isZero() : isSameDirection(machineConfiguration.getSpindleAxis(), getForwardDirection(_section))) || settings.workPlaneMethod.optimizeType == OPTIMIZE_HEADS || settings.workPlaneMethod.optimizeType == OPTIMIZE_TABLES || settings.workPlaneMethod.optimizeType == OPTIMIZE_BOTH)) { _tcp = false; } return _tcp; } // <<<<< INCLUDED FROM include_files/defineWorkPlane.cpi // >>>>> INCLUDED FROM include_files/getWorkPlaneMachineABC.cpi validate(settings.machineAngles, "Setting 'machineAngles' is required but not defined."); function getWorkPlaneMachineABC(_section, rotate) { var currentABC = isFirstSection() ? new Vector(0, 0, 0) : getCurrentABC(); var abc = _section.getABCByPreference(machineConfiguration, _section.workPlane, currentABC, settings.machineAngles.controllingAxis, settings.machineAngles.type, settings.machineAngles.options); if (!isSameDirection(machineConfiguration.getDirection(abc), _section.workPlane.forward)) { error(localize("Orientation not supported.")); } if (rotate) { if (settings.workPlaneMethod.optimizeType == undefined || settings.workPlaneMethod.useTiltedWorkplane) { // legacy var useTCP = false; var R = machineConfiguration.getRemainingOrientation(abc, _section.workPlane); setRotation(useTCP ? _section.workPlane : R); } else { if (!_section.isOptimizedForMachine()) { machineConfiguration.setToolLength(getSetting("workPlaneMethod.compensateToolLength", false) ? getBodyLength(_section.getTool()) : 0); // define the tool length for head adjustments _section.optimize3DPositionsByMachine(machineConfiguration, abc, settings.workPlaneMethod.optimizeType); } } } return abc; } // <<<<< INCLUDED FROM include_files/getWorkPlaneMachineABC.cpi // >>>>> INCLUDED FROM include_files/writeToolCall.cpi function writeToolCall(tool, insertToolCall) { if (!isFirstSection()) { writeStartBlocks(!getProperty("safeStartAllOperations") && insertToolCall, function () { writeRetract(Z); // write optional Z retract before tool change if safeStartAllOperations is enabled }); } writeStartBlocks(insertToolCall, function () { writeRetract(Z); if (getSetting("retract.homeXY.onToolChange", false)) { writeRetract(settings.retract.homeXY.onToolChange); } if (!isFirstSection() && insertToolCall) { if (typeof forceWorkPlane == "function") { forceWorkPlane(); } onCommand(COMMAND_COOLANT_OFF); // turn off coolant on tool change if (typeof disableLengthCompensation == "function") { disableLengthCompensation(false); } } if (tool.manualToolChange) { onCommand(COMMAND_STOP); writeComment("MANUAL TOOL CHANGE TO T" + toolFormat.format(tool.number)); } else { if (!isFirstSection() && getProperty("optionalStop") && insertToolCall) { onCommand(COMMAND_OPTIONAL_STOP); } onCommand(COMMAND_LOAD_TOOL); } }); if (typeof forceModals == "function" && (insertToolCall || getProperty("safeStartAllOperations"))) { forceModals(); } } // <<<<< INCLUDED FROM include_files/writeToolCall.cpi // >>>>> INCLUDED FROM include_files/startSpindle.cpi function startSpindle(tool, insertToolCall) { if (tool.type != TOOL_PROBE) { var spindleSpeedIsRequired = insertToolCall || forceSpindleSpeed || isFirstSection() || rpmFormat.areDifferent(spindleSpeed, sOutput.getCurrent()) || (tool.clockwise != getPreviousSection().getTool().clockwise); writeStartBlocks(spindleSpeedIsRequired, function () { if (spindleSpeedIsRequired || operationNeedsSafeStart) { onCommand(COMMAND_START_SPINDLE); } }); } } // <<<<< INCLUDED FROM include_files/startSpindle.cpi // >>>>> INCLUDED FROM include_files/workPlaneFunctions_fanuc.cpi var gRotationModal = createOutputVariable({current : 69, onchange: function () { state.twpIsActive = gRotationModal.getCurrent() != 69; if (typeof probeVariables != "undefined") { probeVariables.outputRotationCodes = probeVariables.probeAngleMethod == "G68"; } machineSimulation({}); // update machine simulation TWP state }}, gFormat); var currentWorkPlaneABC = undefined; function forceWorkPlane() { currentWorkPlaneABC = undefined; } function cancelWCSRotation() { if (typeof gRotationModal != "undefined" && gRotationModal.getCurrent() == 68) { cancelWorkPlane(true); } } function cancelWorkPlane(force) { if (typeof gRotationModal != "undefined") { if (force) { gRotationModal.reset(); } var command = gRotationModal.format(69); if (command) { writeBlock(command); // cancel frame forceWorkPlane(); } } } function setWorkPlane(abc) { if (!settings.workPlaneMethod.forceMultiAxisIndexing && is3D() && !machineConfiguration.isMultiAxisConfiguration()) { return; // ignore } var workplaneIsRequired = (currentWorkPlaneABC == undefined) || abcFormat.areDifferent(abc.x, currentWorkPlaneABC.x) || abcFormat.areDifferent(abc.y, currentWorkPlaneABC.y) || abcFormat.areDifferent(abc.z, currentWorkPlaneABC.z); writeStartBlocks(workplaneIsRequired, function () { writeRetract(Z); if (getSetting("retract.homeXY.onIndexing", false)) { writeRetract(settings.retract.homeXY.onIndexing); } if ((state.lengthCompensationActive || state.tcpIsActive) && typeof disableLengthCompensation == "function") { disableLengthCompensation(); // cancel tool lenght compensation / TCP prior to output TWP } if (settings.workPlaneMethod.useTiltedWorkplane) { onCommand(COMMAND_UNLOCK_MULTI_AXIS); cancelWorkPlane(); if (machineConfiguration.isMultiAxisConfiguration()) { var machineABC = abc.isNonZero() ? (currentSection.isMultiAxis() ? getCurrentDirection() : getWorkPlaneMachineABC(currentSection, false)) : abc; if (settings.workPlaneMethod.useABCPrepositioning || machineABC.isZero()) { positionABC(machineABC); } else { setCurrentABC(machineABC); } } if (abc.isNonZero() || !machineConfiguration.isMultiAxisConfiguration()) { gRotationModal.reset(); writeBlock( gRotationModal.format(68.2), "X" + xyzFormat.format(currentSection.workOrigin.x), "Y" + xyzFormat.format(currentSection.workOrigin.y), "Z" + xyzFormat.format(currentSection.workOrigin.z), "I" + abcFormat.format(abc.x), "J" + abcFormat.format(abc.y), "K" + abcFormat.format(abc.z) ); // set frame writeBlock(gFormat.format(53.1)); // turn machine machineSimulation({a:getCurrentABC().x, b:getCurrentABC().y, c:getCurrentABC().z, coordinates:MACHINE, eulerAngles:abc}); } } else { positionABC(abc, true); } if (!currentSection.isMultiAxis()) { onCommand(COMMAND_LOCK_MULTI_AXIS); } currentWorkPlaneABC = abc; }); } // <<<<< INCLUDED FROM include_files/workPlaneFunctions_fanuc.cpi