diff --git a/kondia-b500.cps b/kondia-b500.cps index 5986d53f7902747a1e692d931fa5178ccfdc7248..97d802fbeab0a0ab0e8a1efc15779abcc539dbad 100644 --- a/kondia-b500.cps +++ b/kondia-b500.cps @@ -1,11 +1,11 @@ /** - Copyright (C) 2012-2022 by Autodesk, Inc. + Copyright (C) 2012-2023 by Autodesk, Inc. All rights reserved. NUM post processor configuration. - $Revision: 43811 9402f830a000e97e8885d344dcc12dc65bf77998 $ - $Date: 2022-05-20 14:56:40 $ + $Revision: 44079 7098e6d148aa6ea195b42597d82fe2f00d0115bb $ + $Date: 2023-07-17 12:38:58 $ FORKID {8B1FC740-38BD-4cb2-9CD5-94A55CBE87A5} */ @@ -13,9 +13,9 @@ description = "NUM"; vendor = "NUM"; vendorUrl = "http://www.num.com"; -legal = "Copyright (C) 2012-2022 by Autodesk, Inc."; +legal = "Copyright (C) 2012-2023 by Autodesk, Inc."; certificationLevel = 2; -minimumRevision = 45702; +minimumRevision = 45917; longDescription = "Generic milling post for NUM."; @@ -23,7 +23,7 @@ extension = "nc"; programNameIsInteger = true; setCodePage("ascii"); -capabilities = CAPABILITY_MILLING; +capabilities = CAPABILITY_MILLING | CAPABILITY_MACHINE_SIMULATION; tolerance = spatial(0.002, MM); minimumChordLength = spatial(0.25, MM); @@ -110,7 +110,7 @@ properties = { description: "If yes is selected, arcs are outputted using radius values rather than IJK.", group : "preferences", type : "boolean", - value : true, + value : false, scope : "post" }, showNotes: { @@ -155,34 +155,16 @@ wcsDefinitions = { ] }; -var permittedCommentChars = " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,=_-"; - -var singleLineCoolant = false; // specifies to output multiple coolant codes in one line rather than in separate lines -// samples: -// {id: COOLANT_THROUGH_TOOL, on: 88, off: 89} -// {id: COOLANT_THROUGH_TOOL, on: [8, 88], off: [9, 89]} -// {id: COOLANT_THROUGH_TOOL, on: "M88 P3 (myComment)", off: "M89"} -var coolants = [ - {id:COOLANT_FLOOD, on:8}, - {id:COOLANT_MIST}, - {id:COOLANT_THROUGH_TOOL, on:7}, - {id:COOLANT_AIR}, - {id:COOLANT_AIR_THROUGH_TOOL}, - {id:COOLANT_SUCTION}, - {id:COOLANT_FLOOD_MIST}, - {id:COOLANT_FLOOD_THROUGH_TOOL}, - {id:COOLANT_OFF, off:9} -]; - var gFormat = createFormat({prefix:"G", width:2, zeropad:true, decimals:0}); var mFormat = createFormat({prefix:"M", width:2, zeropad:true, decimals:0}); var hFormat = createFormat({prefix:"H", width:2, zeropad:true, decimals:0}); -var dFormat = createFormat({prefix:"D", width:2, zeropad:true, decimals:0}); +var diameterOffsetFormat = createFormat({prefix:"D", width:2, zeropad:true, decimals:0}); 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 ? 0 : 1), forceDecimal:true}); +var pitchFormat = createFormat({decimals:(unit == MM ? 3 : 4), forceDecimal:true}); var toolFormat = createFormat({width:2, zeropad:true, decimals:0}); var rpmFormat = createFormat({decimals:0}); var secFormat = createFormat({decimals:2, forceDecimal:true}); // seconds - range 0.01-99.99 @@ -195,8 +177,8 @@ 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 pitchOutput = createVariable({prefix:"K", force:true}, pitchFormat); var sOutput = createVariable({prefix:"S", force:true}, rpmFormat); -var dOutput = createVariable({}, dFormat); // circular output var iOutput = createVariable({prefix:"I", force:true}, xyzFormat); @@ -210,75 +192,69 @@ var gFeedModeModal = createModal({}, gFormat); // modal group 5 // G93-94 var gUnitModal = createModal({}, gFormat); // modal group 6 // G70-71 var gCycleModal = createModal({}, gFormat); // modal group 9 // G81, ... var gRetractModal = createModal({}, gFormat); // modal group 10 // G98-99 +var mClampModal = createModalGroup( + {strict:false}, + [ + [10, 11] // 4th axis clamp / unclamp + //[12, 13] // 5th axis clamp / unclamp + ], + mFormat +); + +var settings = { + coolant: { + // samples: + // {id: COOLANT_THROUGH_TOOL, on: 88, off: 89} + // {id: COOLANT_THROUGH_TOOL, on: [8, 88], off: [9, 89]} + // {id: COOLANT_THROUGH_TOOL, on: "M88 P3 (myComment)", off: "M89"} + coolants: [ + {id:COOLANT_FLOOD, on:8}, + {id:COOLANT_MIST, on:7}, + {id:COOLANT_THROUGH_TOOL}, + {id:COOLANT_AIR}, + {id:COOLANT_AIR_THROUGH_TOOL}, + {id:COOLANT_SUCTION}, + {id:COOLANT_FLOOD_MIST}, + {id:COOLANT_FLOOD_THROUGH_TOOL}, + {id:COOLANT_OFF, off:9} + ], + singleLineCoolant: false, // specifies to output multiple coolant codes in one line rather than in separate lines + }, + retract: { + cancelRotationOnRetracting: false, // specifies that rotations (G68) need to be canceled prior to retracting + methodXY : undefined, // special condition, overwrite retract behavior per axis + methodZ : undefined, // special condition, overwrite retract behavior per axis + useZeroValues : ["G28", "G30"] // enter property value id(s) for using "0" value instead of machineConfiguration axes home position values (ie G30 Z0) + }, + 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 : true, // cancel tilted workplane prior to WCS (G54-G59) blocks + useABCPrepositioning : false, // position ABC axes prior to tilted workplane blocks + forceMultiAxisIndexing: false, // force multi-axis indexing for 3D programs + optimizeType : undefined // can be set to OPTIMIZE_NONE, OPTIMIZE_BOTH, OPTIMIZE_TABLES, OPTIMIZE_HEADS, OPTIMIZE_AXIS. 'undefined' uses legacy rotations + }, + comments: { + permittedCommentChars: " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,=_-:", + prefix : "(", // specifies the prefix for the comment + suffix : ")", // specifies the suffix for the comment + upperCase : true, // set to true to output all comments in upper case + maximumLineLength : 80, // the maximum number of charaters allowed in a line, set to 0 to disable comment output + }, + maximumSequenceNumber : undefined, // the maximum sequence number (Nxxx), use 'undefined' for unlimited + supportsOptionalBlocks : false, // specifies if optional block output is supported + supportsTCP : false, // specifies if the postprocessor does support TCP + outputToolLengthCompensation: false, // specifies if tool length compensation code should be output (G43) + outputToolLengthOffset : false // specifies if tool length offset code should be output (Hxx) +}; -// collected state -var sequenceNumber; -var forceSpindleSpeed = false; -var currentWorkOffset; -var retracted = false; // specifies that the tool has been retracted to the safe plane - -/** - Writes the specified block. -*/ -function writeBlock() { - if (!formatWords(arguments)) { - return; - } - if (getProperty("showSequenceNumbers") == "true") { - writeWords2("N" + sequenceNumber, arguments); - sequenceNumber += getProperty("sequenceNumberIncrement"); - } else { - writeWords(arguments); - } -} - -/** - 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); -} - -/** - Output a comment. -*/ -function writeComment(text) { - writeln("(" + filterText(String(text).toUpperCase(), permittedCommentChars) + ")"); -} - -function onOpen() { - if (getProperty("useRadius")) { - maximumCircularSweep = toRad(90); // avoid potential center calculation errors for CNC - } - - 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 - } - - if (!machineConfiguration.isMachineCoordinate(0)) { - aOutput.disable(); - } - if (!machineConfiguration.isMachineCoordinate(1)) { - bOutput.disable(); - } - if (!machineConfiguration.isMachineCoordinate(2)) { - cOutput.disable(); - } - - if (!getProperty("separateWordsWithSpace")) { - setWordSeparator(""); - } - - sequenceNumber = getProperty("sequenceNumberStart"); - +function writeProgramNumber() { if (programName) { var programId; try { @@ -290,481 +266,139 @@ function onOpen() { if (programId > 9000) { warning(localize("Using NUM reserved program number.")); } - if (programComment) { - writeln("%" + programId + " (" + filterText(String(programComment).toUpperCase(), permittedCommentChars) + ")"); - } else { - writeln("%" + programId); - } + writeln("%" + programId + conditional(programComment, " " + formatComment(programComment))); } else { writeln("%"); } +} - // dump machine configuration - var vendor = machineConfiguration.getVendor(); - var model = machineConfiguration.getModel(); - var description = machineConfiguration.getDescription(); - - if (getProperty("writeMachine") && (vendor || model || description)) { - writeComment(localize("Machine")); - if (vendor) { - writeComment(" " + localize("vendor") + ": " + vendor); - } - if (model) { - writeComment(" " + localize("model") + ": " + model); - } - if (description) { - writeComment(" " + localize("description") + ": " + description); - } +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 - // dump tool information - if (getProperty("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 (getProperty("useRadius")) { + maximumCircularSweep = toRad(90); // avoid potential center calculation errors for CNC + } + if (!getProperty("separateWordsWithSpace")) { + setWordSeparator(""); } + writeProgramNumber(); + writeProgramHeader(); // absolute coordinates and feed per min writeBlock(gAbsIncModal.format(90), gFeedModeModal.format(94), gPlaneModal.format(17)); - - switch (unit) { - case IN: - writeBlock(gUnitModal.format(70)); - break; - case MM: - writeBlock(gUnitModal.format(71)); - break; - } -} - -function onComment(message) { - var comments = String(message).split(";"); - for (comment in comments) { - writeComment(comments[comment]); - } -} - -/** 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(); - feedOutput.reset(); + writeBlock(gUnitModal.format(unit == MM ? 71 : 70)); + validateCommonParameters(); } function onParameter(name, value) { } -var currentWorkPlaneABC = undefined; - -function forceWorkPlane() { - currentWorkPlaneABC = undefined; -} - -function positionABC(abc, force) { - if (typeof unwindABC == "function") { - unwindABC(abc, false); - } - 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) { - if (!retracted) { - if (typeof moveToSafeRetractPosition == "function") { - moveToSafeRetractPosition(); - } else { - writeRetract(Z); - } +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) { + if (insertToolCall && !isFirstSection()) { + onCommand(COMMAND_STOP_SPINDLE); // stop spindle before retract during tool change } - onCommand(COMMAND_UNLOCK_MULTI_AXIS); - writeBlock(gMotionModal.format(0), a, b, c); - currentMachineABC = new Vector(abc); - setCurrentABC(abc); // required for machine simulation + writeRetract(Z); // retract } -} -function setWorkPlane(abc) { - if (!machineConfiguration.isMultiAxisConfiguration()) { - return; // ignore - } + writeComment(getParameter("operation-comment", "")); - if (!((currentWorkPlaneABC == undefined) || - abcFormat.areDifferent(abc.x, currentWorkPlaneABC.x) || - abcFormat.areDifferent(abc.y, currentWorkPlaneABC.y) || - abcFormat.areDifferent(abc.z, currentWorkPlaneABC.z))) { - return; // no change + if (getProperty("showNotes")) { + writeSectionNotes(); } - positionABC(abc, true); - onCommand(COMMAND_LOCK_MULTI_AXIS); - currentWorkPlaneABC = abc; -} - -var closestABC = false; // choose closest machine angles -var currentMachineABC; + // tool change + writeToolCall(tool, insertToolCall); + startSpindle(tool, insertToolCall); -function getWorkPlaneMachineABC(workPlane) { - var W = workPlane; // map to global frame + // Output modal commands here + writeBlock(gAbsIncModal.format(90), gFeedModeModal.format(94), gPlaneModal.format(17)); - var abc = machineConfiguration.getABC(W); - if (closestABC) { - if (currentMachineABC) { - abc = machineConfiguration.remapToABC(abc, currentMachineABC); - } else { - abc = machineConfiguration.getPreferredABC(abc); - } - } else { - abc = machineConfiguration.getPreferredABC(abc); - } + forceXYZ(); + var abc = defineWorkPlane(currentSection, true); - 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)) - ); - } + setCoolant(tool.coolant); // writes the required coolant codes - var direction = machineConfiguration.getDirection(abc); - if (!isSameDirection(direction, W.forward)) { - error(localize("Orientation not supported.")); - } + forceAny(); - 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)) - ); - } + // prepositioning + var initialPosition = getFramePosition(currentSection.getInitialPosition()); + var isRequired = insertToolCall || retracted || !lengthCompensationActive || (!isFirstSection() && getPreviousSection().isMultiAxis()); + writeInitialPositioning(initialPosition, isRequired); +} - var tcp = true; - if (tcp) { - setRotation(W); // TCP mode - } else { - var O = machineConfiguration.getOrientation(abc); - var R = machineConfiguration.getRemainingOrientation(abc, W); - setRotation(R); +function onDwell(seconds) { + if (seconds > 99.99) { + warning(localize("Dwelling time is out of range.")); } - - return abc; + seconds = clamp(0.01, seconds, 99.99); + writeBlock(gFormat.format(4), "F" + secFormat.format(seconds)); } -function isProbeOperation() { - return (hasParameter("operation-strategy") && - getParameter("operation-strategy") == "probe"); +function onSpindleSpeed(spindleSpeed) { + writeBlock(sOutput.format(spindleSpeed)); } -function onSection() { - var insertToolCall = isFirstSection() || - currentSection.getForceToolChange && currentSection.getForceToolChange() || - (tool.number != getPreviousSection().getTool().number); - - 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()) || - (currentSection.isOptimizedForMachine() && getPreviousSection().isOptimizedForMachine() && - Vector.diff(getPreviousSection().getFinalToolAxisABC(), currentSection.getInitialToolAxisABC()).length > 1e-4) || - (!machineConfiguration.isMultiAxisConfiguration() && currentSection.isMultiAxis()) || - (!getPreviousSection().isMultiAxis() && currentSection.isMultiAxis() || - getPreviousSection().isMultiAxis() && !currentSection.isMultiAxis()); // force newWorkPlane between indexing and simultaneous operations - if (insertToolCall || newWorkOffset || newWorkPlane) { - - // stop spindle before retract during tool change - if (insertToolCall && !isFirstSection()) { - onCommand(COMMAND_STOP_SPINDLE); - } +function onCycle() { + writeBlock(gPlaneModal.format(17)); +} - // retract to safe plane - writeRetract(Z); - zOutput.reset(); +function getCommonCycle(x, y, z, er, cl) { + forceXYZ(); + if (getProperty("controllerType") == "NUM10x0") { + return [xOutput.format(x), yOutput.format(y), + zOutput.format(z), + "EH" + xyzFormat.format(er), + "ER" + xyzFormat.format(cl)]; + } else { + return [xOutput.format(x), yOutput.format(y), + zOutput.format(z), + "ER" + xyzFormat.format(er)]; } +} - if (hasParameter("operation-comment")) { - var comment = getParameter("operation-comment"); - if (comment) { - writeComment(comment); - } +function onCyclePoint(x, y, z) { + var forward; + if (currentSection.isOptimizedForMachine()) { + forward = machineConfiguration.getOptimizedDirection(currentSection.workPlane.forward, getCurrentDirection(), false, false); + } else { + forward = getRotation().forward; } - if (getProperty("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 (!isSameDirection(forward, new Vector(0, 0, 1))) { + expandCyclePoint(x, y, z); + return; + } + // check if we can group the drilling or not + var cycleRequiresRetract = xyzFormat.areDifferent(cycle.retract, cycle.clearance); + if (getProperty("controllerType") == "NUM10x0") { + cycleRequiresRetract = false; // retract handled by EH/ER } - if (insertToolCall) { - forceWorkPlane(); - - setCoolant(COOLANT_OFF); - - if (!isFirstSection() && getProperty("optionalStop")) { - onCommand(COMMAND_OPTIONAL_STOP); - } - - if (tool.number > 99) { - warning(localize("Tool number exceeds maximum value.")); - } + if (isFirstCyclePoint() || cycleRequiresRetract) { + repositionToCycleClearance(cycle, getCurrentPosition().x, getCurrentPosition().y, z); - writeToolBlock("T" + toolFormat.format(tool.number), ("D" + toolFormat.format(tool.diameterOffset)), mFormat.format(6)); - //writeToolBlock("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()); - } - } + // return to initial Z which is clearance plane and set absolute mode - if (getProperty("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)); - } - } - } - } + var F = cycle.feedrate; + var EF = (cycle.dwell == 0) ? 0 : clamp(0.01, cycle.dwell, 99.99); // in seconds - var spindleChanged = tool.type != TOOL_PROBE && - (insertToolCall || forceSpindleSpeed || isFirstSection() || - (rpmFormat.areDifferent(spindleSpeed, sOutput.getCurrent())) || - (tool.clockwise != getPreviousSection().getTool().clockwise)); - if (spindleChanged) { - forceSpindleSpeed = false; - if (spindleSpeed < 1) { - error(localize("Spindle speed out of range.")); - return; - } - if (spindleSpeed > 99999) { - warning(localize("Spindle speed exceeds maximum value.")); - } - if (tool.type == TOOL_TAP_LEFT_HAND) { - writeBlock( - gFormat.format(97), sOutput.format(spindleSpeed), mFormat.format(4) - ); - } else { + switch (cycleType) { + case "drilling": writeBlock( - gFormat.format(97), sOutput.format(spindleSpeed), mFormat.format(tool.clockwise ? 3 : 4) - ); - } - } - // wcs - var workOffset = currentSection.workOffset; - if (!isFirstSection() && (getPreviousSection().workOffset != workOffset)) { // work offset changes) - error(localize("Multiple work offsets are not supported.")); - return; - } - - // writeBlock(currentSection.wcs); - - forceXYZ(); - - if (machineConfiguration.isMultiAxisConfiguration()) { // use 5-axis indexing for multi-axis mode - var abc = new Vector(0, 0, 0); - if (currentSection.isMultiAxis()) { - forceWorkPlane(); - cancelTransformation(); - if (currentSection.isOptimizedForMachine()) { - abc = currentSection.getInitialToolAxisABC(); - positionABC(abc, true); - } - } 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 - setCoolant(tool.coolant); - - forceAny(); - gMotionModal.reset(); - - var initialPosition = getFramePosition(currentSection.getInitialPosition()); - if (!retracted && !insertToolCall) { - if (getCurrentPosition().z < initialPosition.z) { - writeBlock(gMotionModal.format(0), zOutput.format(initialPosition.z)); - } - } - - 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) - ); - } -} - -function onDwell(seconds) { - if (seconds > 99.99) { - warning(localize("Dwelling time is out of range.")); - } - seconds = clamp(0.01, seconds, 99.99); - writeBlock(gFormat.format(4), "F" + secFormat.format(seconds)); -} - -function onSpindleSpeed(spindleSpeed) { - writeBlock(sOutput.format(spindleSpeed)); -} - -function onCycle() { - writeBlock(gPlaneModal.format(17)); -} - -function getCommonCycle(x, y, z, er, cl) { - forceXYZ(); - if (getProperty("controllerType") == "NUM10x0") { - return [xOutput.format(x), yOutput.format(y), - zOutput.format(z), - "EH" + xyzFormat.format(er), - "ER" + xyzFormat.format(cl)]; - } else { - return [xOutput.format(x), yOutput.format(y), - zOutput.format(z), - "ER" + xyzFormat.format(er)]; - } -} - -function onCyclePoint(x, y, z) { - if (!isSameDirection(getRotation().forward, new Vector(0, 0, 1))) { - expandCyclePoint(x, y, z); - return; - } - // check if we can group the drilling or not - var cycleRequiresRetract = xyzFormat.areDifferent(cycle.retract, cycle.clearance); - if (getProperty("controllerType") == "NUM10x0") { - cycleRequiresRetract = false; // retract handled by EH/ER - } - - if (isFirstCyclePoint() || cycleRequiresRetract) { - repositionToCycleClearance(cycle, getCurrentPosition().x, getCurrentPosition().y, z); - - // return to initial Z which is clearance plane and set absolute mode - - var F = cycle.feedrate; - var EF = (cycle.dwell == 0) ? 0 : clamp(0.01, cycle.dwell, 99.99); // in seconds - - switch (cycleType) { - case "drilling": - writeBlock( - gAbsIncModal.format(90), gCycleModal.format(81), - getCommonCycle(x, y, z, cycle.retract, cycle.clearance), - feedOutput.format(F) + gAbsIncModal.format(90), gCycleModal.format(81), + getCommonCycle(x, y, z, cycle.retract, cycle.clearance), + feedOutput.format(F) ); break; case "counter-boring": @@ -806,6 +440,12 @@ function onCyclePoint(x, y, z) { ); break; case "tapping": + writeBlock( + gAbsIncModal.format(90), gCycleModal.format(84), + getCommonCycle(x, y, z, cycle.retract, cycle.clearance), + pitchOutput.format(tool.threadPitch) + ); + break case "left-tapping": case "right-tapping": if (!F) { @@ -902,26 +542,6 @@ function onCycleEnd() { } } -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); - feedOutput.reset(); - } -} - function onLinear(_x, _y, _z, feed) { var x = xOutput.format(_x); var y = yOutput.format(_y); @@ -930,18 +550,13 @@ function onLinear(_x, _y, _z, 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.")); - } + var d = diameterOffsetFormat.format(tool.diameterOffset); switch (radiusCompensation) { case RADIUS_COMPENSATION_LEFT: - dOutput.reset(); - writeBlock(gPlaneModal.format(17), dOutput.format(d), gMotionModal.format(1), gFormat.format(41), x, y, z, f); + writeBlock(gPlaneModal.format(17), d, gMotionModal.format(1), gFormat.format(41), x, y, z, f); break; case RADIUS_COMPENSATION_RIGHT: - dOutput.reset(); - writeBlock(gPlaneModal.format(17), dOutput.format(d), gMotionModal.format(1), gFormat.format(42), x, y, z, f); + writeBlock(gPlaneModal.format(17), d, gMotionModal.format(1), gFormat.format(42), x, y, z, f); break; default: writeBlock(gMotionModal.format(1), gFormat.format(40), x, y, z, f); @@ -958,58 +573,11 @@ function onLinear(_x, _y, _z, feed) { } } -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); - feedOutput.reset(); -} - -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 = feedOutput.format(feed); - if (x || y || z || a || b || c) { - writeBlock(gMotionModal.format(1), x, y, z, a, b, c, f); - } else if (f) { - if (getNextRecord().isMotion()) { // try not to output feed without motion - feedOutput.reset(); // force feed on next line - } else { - writeBlock(gMotionModal.format(1), f); - } - } -} - function 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; } - switch (getCircularPlane()) { case PLANE_XY: xOutput.reset(); @@ -1080,105 +648,20 @@ function onCircular(clockwise, cx, cy, cz, x, y, z, feed) { } } -var currentCoolantMode = COOLANT_OFF; -var coolantOff = undefined; -var forceCoolant = false; - -function setCoolant(coolant) { - var coolantCodes = getCoolantCodes(coolant); - if (Array.isArray(coolantCodes)) { - if (singleLineCoolant) { - writeBlock(coolantCodes.join(getWordSeparator())); - } else { - for (var c in coolantCodes) { - writeBlock(coolantCodes[c]); - } - } - return undefined; - } - return coolantCodes; -} - -function getCoolantCodes(coolant) { - var multipleCoolantBlocks = new Array(); // create a formatted array to be passed into the outputted line - if (!coolants) { - error(localize("Coolants have not been defined.")); - } - if (tool.type == TOOL_PROBE) { // avoid coolant output for probing - coolant = COOLANT_OFF; - } - if (coolant == currentCoolantMode && (!forceCoolant || coolant == COOLANT_OFF)) { - return undefined; // coolant is already active - } - if ((coolant != COOLANT_OFF) && (currentCoolantMode != COOLANT_OFF) && (coolantOff != undefined) && !forceCoolant) { - if (Array.isArray(coolantOff)) { - for (var i in coolantOff) { - multipleCoolantBlocks.push(coolantOff[i]); - } - } else { - multipleCoolantBlocks.push(coolantOff); - } - } - forceCoolant = false; - - var m; - var coolantCodes = {}; - for (var c in coolants) { // find required coolant codes into the coolants array - if (coolants[c].id == coolant) { - coolantCodes.on = coolants[c].on; - if (coolants[c].off != undefined) { - coolantCodes.off = coolants[c].off; - break; - } else { - for (var i in coolants) { - if (coolants[i].id == COOLANT_OFF) { - coolantCodes.off = coolants[i].off; - break; - } - } - } - } - } - if (coolant == COOLANT_OFF) { - m = !coolantOff ? coolantCodes.off : coolantOff; // use the default coolant off command when an 'off' value is not specified - } else { - coolantOff = coolantCodes.off; - m = coolantCodes.on; - } - - if (!m) { - onUnsupportedCoolant(coolant); - m = 9; - } else { - if (Array.isArray(m)) { - for (var i in m) { - multipleCoolantBlocks.push(m[i]); - } - } else { - multipleCoolantBlocks.push(m); - } - currentCoolantMode = coolant; - for (var i in multipleCoolantBlocks) { - if (typeof multipleCoolantBlocks[i] == "number") { - multipleCoolantBlocks[i] = mFormat.format(multipleCoolantBlocks[i]); - } - } - return multipleCoolantBlocks; // return the single formatted coolant value - } - return undefined; -} - var mapCommand = { - COMMAND_END : 2, - COMMAND_SPINDLE_CLOCKWISE : 3, - COMMAND_SPINDLE_COUNTERCLOCKWISE: 4, - COMMAND_STOP_SPINDLE : 5, - COMMAND_ORIENTATE_SPINDLE : 19, - COMMAND_LOAD_TOOL : 6 + COMMAND_END : 2, + COMMAND_STOP_SPINDLE : 5, + COMMAND_ORIENTATE_SPINDLE: 19 }; function onCommand(command) { switch (command) { + case COMMAND_COOLANT_OFF: + setCoolant(COOLANT_OFF); + return; + case COMMAND_COOLANT_ON: + setCoolant(tool.coolant); + return; case COMMAND_STOP: writeBlock(mFormat.format(0)); forceSpindleSpeed = true; @@ -1189,18 +672,24 @@ function onCommand(command) { forceSpindleSpeed = true; forceCoolant = true; return; - case COMMAND_COOLANT_ON: - return; - case COMMAND_COOLANT_OFF: - return; case COMMAND_START_SPINDLE: - onCommand(tool.clockwise ? COMMAND_SPINDLE_CLOCKWISE : COMMAND_SPINDLE_COUNTERCLOCKWISE); + forceSpindleSpeed = false; + writeBlock(gFormat.format(97), sOutput.format(spindleSpeed), mFormat.format(tool.clockwise ? 3 : 4)); + return; + case COMMAND_LOAD_TOOL: + writeToolBlock("T" + toolFormat.format(tool.number), mFormat.format(6)); + writeComment(tool.comment); + + var preloadTool = getNextTool(tool.number != getFirstTool().number); + if (getProperty("preloadTool") && preloadTool) { + writeBlock("T" + toolFormat.format(preloadTool.number)); // preload next/first tool + } return; case COMMAND_LOCK_MULTI_AXIS: - writeBlock(mFormat.format(10)); + writeBlock(mClampModal.format(10)); return; case COMMAND_UNLOCK_MULTI_AXIS: - writeBlock(mFormat.format(11)); + writeBlock(mClampModal.format(11)); return; case COMMAND_BREAK_CONTROL: return; @@ -1220,10 +709,6 @@ function onCommand(command) { function onSectionEnd() { if (currentSection.isMultiAxis()) { writeBlock(gMotionModal.format(49)); - // the code below gets the machine angles from previous operation. closestABC must also be set to true - if (currentSection.isOptimizedForMachine()) { - currentMachineABC = currentSection.getFinalToolAxisABC(); - } } if (!isLastSection() && (getNextSection().getTool().coolant != tool.coolant)) { setCoolant(COOLANT_OFF); @@ -1232,46 +717,439 @@ function onSectionEnd() { forceAny(); } -/** Output block to do safe retract and/or move to home position. */ function writeRetract() { - var words = []; // store all retracted axes in an array - var retractAxes = new Array(false, false, false); - var method = getProperty("safePositionMethod"); - if (method == "clearanceHeight") { - if (!is3D()) { - error(localize("Safe retract option 'Clearance Height' is only supported when all operations are along the setup Z-axis.")); + var retract = getRetractParameters.apply(this, arguments); + if (retract && retract.words.length > 0) { + if (typeof gRotationModal != "undefined" && gRotationModal.getCurrent() == 68 && settings.retract.cancelRotationOnRetracting) { // cancel rotation before retracting + cancelWorkPlane(true); } + switch (retract.method) { + case "G52": + gMotionModal.reset(); + writeBlock(gAbsIncModal.format(90), gFormat.format(52), gMotionModal.format(0), retract.words); + break; + default: + error(localize("Unsupported safe position method.")); + return; + } + } +} + +function onClose() { + setCoolant(COOLANT_OFF); + writeRetract(Z); + setWorkPlane(new Vector(0, 0, 0)); // reset working plane + writeRetract(X, Y); + writeBlock(mFormat.format(2)); // stop program + writeln(DC3); // XOFF +} + +// >>>>> INCLUDED FROM include_files/commonFunctions.cpi +// internal variables, do not change +var receivedMachineConfiguration; +var tcp = {isSupportedByControl:getSetting("supportsTCP", true), isSupportedByMachine:false, isSupportedByOperation:false}; +var multiAxisFeedrate; +var sequenceNumber; +var optionalSection = false; +var currentWorkOffset; +var forceSpindleSpeed = false; +var retracted = false; // specifies that the tool has been retracted to the safe plane +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 = getProperty("useABCPrepositioning") != undefined ? getProperty("useABCPrepositioning") : + getSetting("workPlaneMethod.useABCPrepositioning", false); + + 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 (machineConfiguration.isHeadConfiguration()) { + compensateToolLength = typeof compensateToolLength == "undefined" ? false : compensateToolLength; + } + + if (machineConfiguration.isHeadConfiguration() && compensateToolLength) { + 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) { + 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) { + error(localize("Using multiple work offsets is not possible if the initial work offset is 0.")); + } + if (section.isMultiAxis()) { + if (!section.isOptimizedForMachine() && !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 (!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; + } + 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) { + if (text) { + writeWords("/", "N" + sequenceNumber, text); + } + } else { + writeWords2("N" + sequenceNumber, arguments); + } + sequenceNumber += getProperty("sequenceNumberIncrement"); + } else { + if (optionalSection || skipBlocks) { + writeWords2("/", arguments); + } else { + writeWords(arguments); + } + } +} + +validate(settings.comments, "Setting 'comments' is required but not defined."); +function formatComment(text) { + var prefix = settings.comments.prefix; + var suffix = settings.comments.suffix; + text = settings.comments.upperCase ? text.toUpperCase() : text; + text = filterText(String(text), settings.comments.permittedCommentChars).replace(/[()]/g, ""); + 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("\n"); + for (comment in comments) { + var _comment = formatComment(comments[comment]); + if (_comment) { + 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); +} + +var skipBlocks = false; +function writeStartBlocks(isRequired, code) { + var safeSkipBlocks = skipBlocks; + if (!isRequired) { + if (!getProperty("safeStartAllOperations", false)) { + return; // when safeStartAllOperations is disabled, dont output code and return + } + // if values are not required, but safe start is enabled - write following blocks as optional + skipBlocks = true; + } + code(); // writes out the code which is passed to this function as an argument + skipBlocks = safeSkipBlocks; // 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; } - validate(arguments.length != 0, "No axis specified for writeRetract()."); +} + +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 getRetractParameters() { + 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]) && !retracted) { // retract Z first before moving to X/Y home error(localize("Retracting in X/Y is not possible without being retracted in Z.")); - return; + return undefined; } // special conditions - /* - if (retractAxes[2]) { // Z doesn't use G53 - method = "G28"; + if (retractAxes[0] || retractAxes[1]) { + method = getSetting("retract.methodXY", method); } - */ - - // define home positions - var _xHome; - var _yHome; - var _zHome; - if (method == "G28") { - _xHome = toPreciseUnit(0, MM); - _yHome = toPreciseUnit(0, MM); - _zHome = toPreciseUnit(0, MM); - } else { - _xHome = machineConfiguration.hasHomePositionX() ? machineConfiguration.getHomePositionX() : toPreciseUnit(0, MM); - _yHome = machineConfiguration.hasHomePositionY() ? machineConfiguration.getHomePositionY() : toPreciseUnit(0, MM); - _zHome = machineConfiguration.getRetractPlane() != 0 ? machineConfiguration.getRetractPlane() : toPreciseUnit(0, MM); + 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: @@ -1285,46 +1163,630 @@ function writeRetract() { case Z: words.push("Z" + xyzFormat.format(_zHome)); zOutput.reset(); - retracted = true; + retracted = (typeof skipBlocks == "undefined") ? true : !skipBlocks; break; default: - error(localize("Unsupported axis specified for writeRetract().")); - return; + error(localize("Unsupported axis specified for getRetractParameters().")); + return undefined; } } - if (words.length > 0) { - switch (method) { - case "G28": - gMotionModal.reset(); - gAbsIncModal.reset(); - writeBlock(gFormat.format(28), gAbsIncModal.format(91), words); - writeBlock(gAbsIncModal.format(90)); - break; - case "G53": - gMotionModal.reset(); - writeBlock(gAbsIncModal.format(90), gFormat.format(53), gMotionModal.format(0), words); - break; - case "G52": - gMotionModal.reset(); - writeBlock(gAbsIncModal.format(90), gFormat.format(52), gMotionModal.format(0), words); - break; - default: - error(localize("Unsupported safe position method.")); + return {method:method, retractAxes:retractAxes, words:words}; +} + +/** Returns true when subprogram logic does exist into the post. */ +function subprogramsAreSupported() { + return typeof subprogramState != "undefined"; +} +// <<<<< INCLUDED FROM include_files/commonFunctions.cpi +// >>>>> INCLUDED FROM include_files/defineMachine.cpi +var compensateToolLength = false; // add the tool length to the pivot distance for nonTCP rotary heads +function defineMachine() { + var useTCP = true; + if (false) { // note: setup your machine here + var aAxis = createAxis({coordinate:0, table:true, axis:[1, 0, 0], range:[-120, 120], preference:1, tcp:useTCP}); + var cAxis = createAxis({coordinate:2, table:true, axis:[0, 0, 1], range:[-360, 360], preference:0, tcp:useTCP}); + machineConfiguration = new MachineConfiguration(aAxis, cAxis); + + setMachineConfiguration(machineConfiguration); + if (receivedMachineConfiguration) { + warning(localize("The provided CAM machine configuration is overwritten by the postprocessor.")); + receivedMachineConfiguration = false; // CAM provided machine configuration is overwritten + } + } + + if (!receivedMachineConfiguration) { + // 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( + useTCP ? FEED_FPM : getProperty("useDPMFeeds") ? FEED_DPM : FEED_INVERSE_TIME, + 9999.99, // maximum output value for inverse time feed rates + getProperty("useDPMFeeds") ? DPM_COMBINATION : 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)); + } +} +// <<<<< INCLUDED FROM include_files/defineMachine.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(); + positionABC(abc, true); + } 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); + } + if (currentSection && (currentSection.getId() == _section.getId())) { + tcp.isSupportedByOperation = currentSection.getOptimizedTCPMode() == OPTIMIZE_NONE; + if (!currentSection.isMultiAxis() && (settings.workPlaneMethod.useTiltedWorkplane || isSameDirection(machineConfiguration.getSpindleAxis(), currentSection.workPlane.forward))) { + tcp.isSupportedByOperation = false; + } + } + return abc; +} +// <<<<< 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) : getCurrentDirection(); + var abc = machineConfiguration.getABCByPreference(_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); + setCurrentDirection(currentABC); // temporary fix for currentDirection + } else { + if (!_section.isOptimizedForMachine()) { + machineConfiguration.setToolLength(compensateToolLength ? _section.getTool().overallLength : 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/positionABC.cpi +function positionABC(abc, force) { + if (typeof unwindABC == "function") { + unwindABC(abc); + } + if (force) { + forceABC(); + } + var a = machineConfiguration.isMultiAxisConfiguration() ? aOutput.format(abc.x) : toolVectorOutputI.format(abc.x); + var b = machineConfiguration.isMultiAxisConfiguration() ? bOutput.format(abc.y) : toolVectorOutputJ.format(abc.y); + var c = machineConfiguration.isMultiAxisConfiguration() ? cOutput.format(abc.z) : toolVectorOutputK.format(abc.z); + if (a || b || c) { + if (!retracted) { + if (typeof moveToSafeRetractPosition == "function") { + moveToSafeRetractPosition(); + } else { + writeRetract(Z); + } + } + onCommand(COMMAND_UNLOCK_MULTI_AXIS); + gMotionModal.reset(); + writeBlock(gMotionModal.format(0), a, b, c); + + if (getCurrentSectionId() != -1) { + setCurrentABC(abc); // required for machine simulation + } + } +} +// <<<<< INCLUDED FROM include_files/positionABC.cpi +// >>>>> INCLUDED FROM include_files/writeWCS.cpi +function writeWCS(section, wcsIsRequired) { + if (section.workOffset != currentWorkOffset) { + if (getSetting("workPlaneMethod.cancelTiltFirst", false) && wcsIsRequired) { + cancelWorkPlane(); + } + if (typeof forceWorkPlane == "function" && wcsIsRequired) { + forceWorkPlane(); + } + writeStartBlocks(wcsIsRequired, function () { + writeBlock(section.wcs); + }); + currentWorkOffset = section.workOffset; + } +} +// <<<<< INCLUDED FROM include_files/writeWCS.cpi +// >>>>> INCLUDED FROM include_files/writeToolCall.cpi +function writeToolCall(tool, insertToolCall) { + if (typeof forceModals == "function" && (insertToolCall || getProperty("safeStartAllOperations"))) { + forceModals(); + } + writeStartBlocks(insertToolCall, function () { + if (!retracted) { + writeRetract(Z); + } + 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); + } + }); +} +// <<<<< 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/coolant.cpi +var currentCoolantMode = COOLANT_OFF; +var coolantOff = undefined; +var isOptionalCoolant = false; +var forceCoolant = false; + +function setCoolant(coolant) { + var coolantCodes = getCoolantCodes(coolant); + if (Array.isArray(coolantCodes)) { + writeStartBlocks(!isOptionalCoolant, function () { + if (settings.coolant.singleLineCoolant) { + writeBlock(coolantCodes.join(getWordSeparator())); + } else { + for (var c in coolantCodes) { + writeBlock(coolantCodes[c]); + } + } + }); + return undefined; + } + return coolantCodes; +} + +function getCoolantCodes(coolant, format) { + isOptionalCoolant = false; + if (typeof operationNeedsSafeStart == "undefined") { + operationNeedsSafeStart = false; + } + var multipleCoolantBlocks = new Array(); // create a formatted array to be passed into the outputted line + var coolants = settings.coolant.coolants; + if (!coolants) { + error(localize("Coolants have not been defined.")); + } + if (tool.type && tool.type == TOOL_PROBE) { // avoid coolant output for probing + coolant = COOLANT_OFF; + } + if (coolant == currentCoolantMode) { + if (operationNeedsSafeStart && coolant != COOLANT_OFF) { + isOptionalCoolant = true; + } else if (!forceCoolant || coolant == COOLANT_OFF) { + return undefined; // coolant is already active + } + } + if ((coolant != COOLANT_OFF) && (currentCoolantMode != COOLANT_OFF) && (coolantOff != undefined) && !forceCoolant && !isOptionalCoolant) { + if (Array.isArray(coolantOff)) { + for (var i in coolantOff) { + multipleCoolantBlocks.push(coolantOff[i]); + } + } else { + multipleCoolantBlocks.push(coolantOff); + } + } + forceCoolant = false; + + var m; + var coolantCodes = {}; + for (var c in coolants) { // find required coolant codes into the coolants array + if (coolants[c].id == coolant) { + coolantCodes.on = coolants[c].on; + if (coolants[c].off != undefined) { + coolantCodes.off = coolants[c].off; + break; + } else { + for (var i in coolants) { + if (coolants[i].id == COOLANT_OFF) { + coolantCodes.off = coolants[i].off; + break; + } + } + } + } + } + if (coolant == COOLANT_OFF) { + m = !coolantOff ? coolantCodes.off : coolantOff; // use the default coolant off command when an 'off' value is not specified + } else { + coolantOff = coolantCodes.off; + m = coolantCodes.on; + } + + if (!m) { + onUnsupportedCoolant(coolant); + m = 9; + } else { + if (Array.isArray(m)) { + for (var i in m) { + multipleCoolantBlocks.push(m[i]); + } + } else { + multipleCoolantBlocks.push(m); + } + currentCoolantMode = coolant; + for (var i in multipleCoolantBlocks) { + if (typeof multipleCoolantBlocks[i] == "number") { + multipleCoolantBlocks[i] = mFormat.format(multipleCoolantBlocks[i]); + } + } + if (format == undefined || format) { + return multipleCoolantBlocks; // return the single formatted coolant value + } else { + return m; // return unformatted coolant value + } + } + return undefined; +} +// <<<<< INCLUDED FROM include_files/coolant.cpi +// >>>>> INCLUDED FROM include_files/writeProgramHeader.cpi +function writeProgramHeader() { + // dump machine configuration + var vendor = machineConfiguration.getVendor(); + var model = machineConfiguration.getModel(); + var mDescription = machineConfiguration.getDescription(); + if (getProperty("writeMachine") && (vendor || model || mDescription)) { + writeComment(localize("Machine")); + if (vendor) { + writeComment(" " + localize("vendor") + ": " + vendor); + } + if (model) { + writeComment(" " + localize("model") + ": " + model); + } + if (mDescription) { + writeComment(" " + localize("description") + ": " + mDescription); + } + } + + // dump tool information + if (getProperty("writeTools")) { + if (false) { // set to true to use the post kernel version of the tool list + writeToolTable(TOOL_NUMBER_COL); + } else { + 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); + } + } + } + } +} +// <<<<< INCLUDED FROM include_files/writeProgramHeader.cpi + +// >>>>> INCLUDED FROM include_files/onRapid_fanuc.cpi +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(); } } +// <<<<< INCLUDED FROM include_files/onRapid_fanuc.cpi +// >>>>> INCLUDED FROM include_files/onRapid5D_fanuc.cpi +function onRapid5D(_x, _y, _z, _a, _b, _c) { + if (pendingRadiusCompensation >= 0) { + error(localize("Radius compensation mode cannot be changed at rapid traversal.")); + return; + } + if (!currentSection.isOptimizedForMachine()) { + forceXYZ(); + } + var x = xOutput.format(_x); + var y = yOutput.format(_y); + var z = zOutput.format(_z); + var a = currentSection.isOptimizedForMachine() ? aOutput.format(_a) : toolVectorOutputI.format(_a); + var b = currentSection.isOptimizedForMachine() ? bOutput.format(_b) : toolVectorOutputJ.format(_b); + var c = currentSection.isOptimizedForMachine() ? cOutput.format(_c) : toolVectorOutputK.format(_c); -function onClose() { - setCoolant(COOLANT_OFF); - writeRetract(Z); - zOutput.reset(); - setWorkPlane(new Vector(0, 0, 0)); // reset working plane - writeRetract(X, Y); - writeBlock(mFormat.format(2)); // stop program - writeln(DC3); // XOFF + if (x || y || z || a || b || c) { + writeBlock(gMotionModal.format(0), x, y, z, a, b, c); + forceFeed(); + } +} +// <<<<< INCLUDED FROM include_files/onRapid5D_fanuc.cpi +// >>>>> INCLUDED FROM include_files/onLinear5D_fanuc.cpi +function onLinear5D(_x, _y, _z, _a, _b, _c, feed, feedMode) { + if (pendingRadiusCompensation >= 0) { + error(localize("Radius compensation cannot be activated/deactivated for 5-axis move.")); + return; + } + if (!currentSection.isOptimizedForMachine()) { + forceXYZ(); + } + var x = xOutput.format(_x); + var y = yOutput.format(_y); + var z = zOutput.format(_z); + var a = currentSection.isOptimizedForMachine() ? aOutput.format(_a) : toolVectorOutputI.format(_a); + var b = currentSection.isOptimizedForMachine() ? bOutput.format(_b) : toolVectorOutputJ.format(_b); + var c = currentSection.isOptimizedForMachine() ? cOutput.format(_c) : toolVectorOutputK.format(_c); + if (feedMode == FEED_INVERSE_TIME) { + forceFeed(); + } + var f = feedMode == FEED_INVERSE_TIME ? inverseTimeOutput.format(feed) : getFeed(feed); + var fMode = feedMode == FEED_INVERSE_TIME ? 93 : getProperty("useG95") ? 95 : 94; + + if (x || y || z || a || b || c) { + writeBlock(gFeedModeModal.format(fMode), gMotionModal.format(1), x, y, z, a, b, c, f); + } else if (f) { + if (getNextRecord().isMotion()) { // try not to output feed without motion + forceFeed(); // force feed on next line + } else { + writeBlock(gFeedModeModal.format(fMode), gMotionModal.format(1), f); + } + } +} +// <<<<< INCLUDED FROM include_files/onLinear5D_fanuc.cpi +// >>>>> INCLUDED FROM include_files/workPlaneFunctions_fanuc.cpi +var currentWorkPlaneABC = undefined; +function forceWorkPlane() { + currentWorkPlaneABC = undefined; +} + +function cancelWorkPlane(force) { + if (typeof gRotationModal != "undefined") { + if (force) { + gRotationModal.reset(); + } + writeBlock(gRotationModal.format(69)); // 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 () { + if (!retracted) { + writeRetract(Z); + } + + if (settings.workPlaneMethod.useTiltedWorkplane) { + onCommand(COMMAND_UNLOCK_MULTI_AXIS); + if (settings.workPlaneMethod.cancelTiltFirst) { + cancelWorkPlane(); + } + if (machineConfiguration.isMultiAxisConfiguration()) { + var machineABC = abc.isNonZero() ? (currentSection.isMultiAxis() ? getCurrentDirection() : getWorkPlaneMachineABC(currentSection, false)) : abc; + if (settings.workPlaneMethod.useABCPrepositioning || machineABC.isZero()) { + positionABC(machineABC, false); + } else { + setCurrentABC(machineABC); + } + } + if (abc.isNonZero()) { + 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 + } else { + if (!settings.workPlaneMethod.cancelTiltFirst) { + cancelWorkPlane(); + } + } + } else { + positionABC(abc, true); + } + if (!currentSection.isMultiAxis()) { + onCommand(COMMAND_LOCK_MULTI_AXIS); + } + currentWorkPlaneABC = abc; + }); } +// <<<<< INCLUDED FROM include_files/workPlaneFunctions_fanuc.cpi +// >>>>> INCLUDED FROM include_files/initialPositioning_fanuc.cpi +/** + * Writes the initial positioning procedure for a section to get to the start position of the toolpath. + * @param {Vector} position The initial position to move to + * @param {boolean} isRequired true: Output full positioning, false: Output full positioning in optional state or output simple positioning only + * @param {String} codes1 Allows to add additional code to the first positioning line + * @param {String} codes2 Allows to add additional code to the second positioning line (if applicable) + * @example + var myVar1 = formatWords("T" + tool.number, currentSection.wcs); + var myVar2 = getCoolantCodes(tool.coolant); + writeInitialPositioning(initialPosition, isRequired, myVar1, myVar2); +*/ +function writeInitialPositioning(position, isRequired, codes1, codes2) { + var motionCode = (highFeedMapping != HIGH_FEED_NO_MAPPING) ? 1 : 0; + var feed = (highFeedMapping != HIGH_FEED_NO_MAPPING) ? getFeed(highFeedrate) : ""; + var gOffset = getSetting("outputToolLengthCompensation", true) ? gFormat.format(getOffsetCode()) : ""; + var hOffset = getSetting("outputToolLengthOffset", true) ? hFormat.format(tool.lengthOffset) : ""; + var additionalCodes = [formatWords(codes1), formatWords(codes2)]; + + forceModals(gMotionModal); + writeStartBlocks(isRequired, function() { + var modalCodes = formatWords(gAbsIncModal.format(90), gPlaneModal.format(17)); + if (typeof disableLengthCompensation == "function") { + disableLengthCompensation(false); // cancel tool length compensation prior to enabling it, required when switching G43/G43.4 modes + } -function setProperty(property, value) { - properties[property].current = value; + // multi axis prepositioning with TWP + if (currentSection.isMultiAxis() && getSetting("workPlaneMethod.prepositionWithTWP", true) && getSetting("workPlaneMethod.useTiltedWorkplane", false) && + tcp.isSupportedByOperation && getCurrentDirection().isNonZero()) { + var W = machineConfiguration.isMultiAxisConfiguration() ? machineConfiguration.getOrientation(getCurrentDirection()) : + Matrix.getOrientationFromDirection(getCurrentDirection()); + var prePosition = W.getTransposed().multiply(position); + var angles = W.getEuler2(settings.workPlaneMethod.eulerConvention); + setWorkPlane(angles); + writeBlock(modalCodes, gMotionModal.format(motionCode), xOutput.format(prePosition.x), yOutput.format(prePosition.y), feed, additionalCodes[0]); + cancelWorkPlane(); + writeBlock(gOffset, hOffset, additionalCodes[1]); // omit Z-axis output is desired + lengthCompensationActive = true; + forceAny(); // required to output XYZ coordinates in the following line + } else { + if (machineConfiguration.isHeadConfiguration()) { + writeBlock(modalCodes, gMotionModal.format(motionCode), gOffset, + xOutput.format(position.x), yOutput.format(position.y), zOutput.format(position.z), + hOffset, feed, additionalCodes + ); + } else { + writeBlock(modalCodes, gMotionModal.format(motionCode), xOutput.format(position.x), yOutput.format(position.y), feed, additionalCodes[0]); + writeBlock(gMotionModal.format(motionCode), gOffset, zOutput.format(position.z), hOffset, additionalCodes[1]); + } + lengthCompensationActive = true; + } + forceModals(gMotionModal); + if (isRequired) { + additionalCodes = []; // clear additionalCodes buffer + } + }); + + validate(lengthCompensationActive, "Tool length compensation is not active."); // make sure that lenght compensation is enabled + if (!isRequired) { // simple positioning + var modalCodes = formatWords(gAbsIncModal.format(90), gPlaneModal.format(17)); + if (!retracted && xyzFormat.getResultingValue(getCurrentPosition().z) < xyzFormat.getResultingValue(position.z)) { + writeBlock(modalCodes, gMotionModal.format(motionCode), zOutput.format(position.z), feed); + } + forceXYZ(); + writeBlock(modalCodes, gMotionModal.format(motionCode), xOutput.format(position.x), yOutput.format(position.y), feed, additionalCodes); + } +} + +Matrix.getOrientationFromDirection = function (ijk) { + var forward = ijk; + var unitZ = new Vector(0, 0, 1); + var W; + if (Math.abs(Vector.dot(forward, unitZ)) < 0.5) { + var imX = Vector.cross(forward, unitZ).getNormalized(); + W = new Matrix(imX, Vector.cross(forward, imX), forward); + } else { + var imX = Vector.cross(new Vector(0, 1, 0), forward).getNormalized(); + W = new Matrix(imX, Vector.cross(forward, imX), forward); + } + return W; +}; +// <<<<< INCLUDED FROM include_files/initialPositioning_fanuc.cpi +// >>>>> INCLUDED FROM include_files/getOffsetCode_fanuc.cpi +function getOffsetCode() { + // assumes a head configuration uses TCP on a Fanuc controller + var offsetCode = 43; + if (currentSection.isMultiAxis()) { + if (machineConfiguration.isMultiAxisConfiguration() && tcp.isSupportedByOperation) { + offsetCode = 43.4; + } else if (!machineConfiguration.isMultiAxisConfiguration()) { + offsetCode = 43.5; + } + } + return offsetCode; } +// <<<<< INCLUDED FROM include_files/getOffsetCode_fanuc.cpi