/** Copyright (C) 2012-2025 by Autodesk, Inc. All rights reserved. HURCO post processor configuration. $Revision: 44166 e813d608ccd22fb0949f73fcdb773b434407b131 $ $Date: 2025-02-19 11:52:14 $ FORKID {1B14E478-26FE-4db2-A3E7-FB814E8C0B4E} */ description = "HURCO"; vendor = "HURCO"; vendorUrl = "http://www.hurco.com"; legal = "Copyright (C) 2012-2025 by Autodesk, Inc."; certificationLevel = 2; minimumRevision = 45917; longDescription = "Generic post for HURCO. Note that this post supports both ISNC (ISO NC mode) and BNC (Basic NC mode). By default ISNC mode is used but you can switch to BNC mode by disabling the 'isnc' property. Also note that you can turn on 3D arcs by enabling the 'Allow 3D arcs' property so you will get arcs in any plane instead of only in the primary planes G17/G18/G19. Note that the HURCO CNC cannot guarantee that no gouging will happen at rewinds when using vector output for multi-axis simultaneous machining as vector does not provide enough information. You need to define the machine or use a machine definition in the post to be safe."; extension = "hnc"; 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; highFeedMapping = HIGH_FEED_MAP_MULTI; probeMultipleFeatures = true; // user-defined properties properties = { preloadTool: { title : "Preload tool", description: "Preloads the next tool at a tool change (if any).", group : "preferences", type : "boolean", value : true, scope : "post" }, showSequenceNumbers: { title : "Use sequence numbers", description: "'Yes' outputs sequence numbers on each block, 'Only on tool change' outputs sequence numbers on tool change blocks only, and 'No' disables the output of sequence numbers.", group : "formats", type : "enum", values : [ {title:"Yes", id:"true"}, {title:"No", id:"false"}, {title:"Only on tool change", id:"toolChange"} ], value: "true", scope: "post" }, sequenceNumberStart: { title : "Start sequence number", description: "The number at which to start the sequence numbers.", group : "formats", type : "integer", value : 1, scope : "post" }, sequenceNumberIncrement: { title : "Sequence number increment", description: "The amount by which the sequence number is incremented by in each block.", group : "formats", type : "integer", value : 1, scope : "post" }, optionalStop: { title : "Optional stop", description: "Outputs optional stop code during when necessary in the code.", group : "preferences", type : "boolean", value : true, scope : "post" }, isnc: { title : "Use ISNC or BNC mode", description: "Selects between ISNC (ISO NC mode) and BNC (Basic NC mode).", group : "formats", type : "boolean", values : [ "Basic NC mode", "ISO NC mode" ], value: true, scope: "post" }, separateWordsWithSpace: { title : "Separate words with space", description: "Adds spaces between words if 'yes' is selected.", group : "formats", type : "boolean", value : true, scope : "post" }, allow3DArcs: { title : "Allow 3D arcs", description: "Specifies whether 3D circular arcs are allowed.", group : "preferences", type : "boolean", value : false, scope : "post" }, showNotes: { title : "Show notes", description: "Writes operation notes as comments in the outputted code.", group : "formats", type : "boolean", value : false, scope : "post" }, useTiltedWorkplane: { title : "Use G68.2", description: "Enable to use G68.2 for 3+2 operations.", group : "multiAxis", type : "boolean", value : true, scope : "post" }, preferredTilt: { title : "Prefer positive tilt", description: "Specifies whether to prefer positive or negative tilt angles. This has only an effect on programs using vectors.", group : "multiAxis", type : "boolean", value : false, scope : "post" }, homeXYonToolChange: { title : "Home XY on tool change", description: "Specifies whether to home the XY axes on tool change. Property 'Safe Retracts' must be set to 'G53' for this to work.", group : "homePositions", type : "enum", values : [ {title:"Disabled", id:"disabled"}, {title:"X", id:"x"}, {title:"Y", id:"y"}, {title:"XY", id:"xy"} ], value: "disabled", scope: "post" }, safePositionMethod: { title : "Safe Retracts", description: "Select your desired retract option. 'Clearance Height' retracts to the operation clearance height.", group : "homePositions", type : "enum", values : [ {title:"G53", id:"G53"}, {title:"Clearance Height", id:"clearanceHeight"} ], value: "G53", scope: "post" }, useM140: { title : "Use M140", description: "Specifies to use M140 for Z-axis retracts instead of G53.", group : "homePositions", type : "boolean", value : true, scope : "post" }, useG43: { title : "Use G43", description: "Enable to use G43 for tool length compensation", group : "preferences", type : "boolean", value : true, scope : "post" }, outputToolDiameterOffset: { title : "Output tool radius compensation code (Dxx)", description: "Enable to output the tool radius compensation code (Dxx), disable to use the control's tool offset table instead.", group : "preferences", type : "boolean", value : true, scope : "post" }, singleResultsFile: { title : "Create single results file", description: "Set to false if you want to store the measurement results for each probe / inspection toolpath in a separate file", group : "probing", type : "boolean", value : true, scope : "post" } }; // wcs definiton wcsDefinitions = { useZeroOffset: false, wcs : [ {name:"Standard", format:"G", range:[54, 59]} ] }; var gFormat = createFormat({prefix:"G", decimals:1}); var mFormat = createFormat({prefix:"M", decimals:0}); var hFormat = createFormat({prefix:"H", decimals:0}); var diameterOffsetFormat = createFormat({prefix:"D", decimals:0}); var probeWCSFormat = createFormat({prefix:"S", decimals:0, type:FORMAT_REAL}); var probeExtWCSFormat = createFormat({prefix:"S", decimals:0, type:FORMAT_REAL, offset:100}); var xyzFormat = createFormat({decimals:(unit == MM ? 3 : 4), type:FORMAT_REAL}); var ijkFormat = createFormat({decimals:6, type:FORMAT_REAL}); var abcFormat = createFormat({decimals:3, type:FORMAT_REAL, scale:DEG}); var feedFormat = createFormat({decimals:(unit == MM ? 1 : 2), type:FORMAT_REAL}); var inverseTimeFormat = createFormat({decimals:3, type:FORMAT_REAL}); var toolFormat = createFormat({decimals:0}); var rpmFormat = createFormat({decimals:0}); var secFormat = createFormat({decimals:3, type:FORMAT_REAL}); // seconds - range 0.001-9999.999 var taperFormat = createFormat({decimals:1, scale:DEG}); var oFormat = createFormat({minDigitsLeft:4, decimals:0}); var xOutput = createOutputVariable({onchange:function() {state.retractedX = false;}, prefix:"X"}, xyzFormat); var yOutput = createOutputVariable({onchange:function() {state.retractedY = false;}, prefix:"Y"}, xyzFormat); var zOutput = createOutputVariable({onchange:function() {state.retractedZ = false;}, prefix:"Z"}, xyzFormat); var toolVectorOutputI = createOutputVariable({prefix:"I", control:CONTROL_FORCE}, ijkFormat); var toolVectorOutputJ = createOutputVariable({prefix:"J", control:CONTROL_FORCE}, ijkFormat); var toolVectorOutputK = createOutputVariable({prefix:"K", control:CONTROL_FORCE}, ijkFormat); var aOutput = createOutputVariable({prefix:"A"}, abcFormat); var bOutput = createOutputVariable({prefix:"B"}, abcFormat); var cOutput = createOutputVariable({prefix:"C"}, abcFormat); var feedOutput = createOutputVariable({prefix:"F"}, feedFormat); var inverseTimeOutput = createOutputVariable({prefix:"F", control:CONTROL_FORCE}, inverseTimeFormat); var sOutput = createOutputVariable({prefix:"S", control:CONTROL_FORCE}, rpmFormat); // circular output var iOutput = createOutputVariable({prefix:"I", control:CONTROL_FORCE}, xyzFormat); var jOutput = createOutputVariable({prefix:"J", control:CONTROL_FORCE}, xyzFormat); var kOutput = createOutputVariable({prefix:"K", control:CONTROL_FORCE}, xyzFormat); var irOutput = createOutputVariable({prefix:"I", control:CONTROL_FORCE}, xyzFormat); var jrOutput = createOutputVariable({prefix:"J", control:CONTROL_FORCE}, xyzFormat); var krOutput = createOutputVariable({prefix:"K", control:CONTROL_FORCE}, xyzFormat); var gMotionModal = createOutputVariable({onchange:function() {if (skipBlocks) {forceModals(gMotionModal);}}}, gFormat); // modal group 1 // G0-G3, ... var gPlaneModal = createOutputVariable({onchange:function() {if (skipBlocks) {forceModals(gPlaneModal);} forceModals(gMotionModal);}}, gFormat); // modal group 2 // G17-19 var gAbsIncModal = createOutputVariable({onchange:function() {if (skipBlocks) {forceModals(gAbsIncModal);}}}, gFormat); // modal group 3 // G90-91 var gFeedModeModal = createOutputVariable({}, gFormat); // modal group 5 // G93-95 var gUnitModal = createOutputVariable({}, gFormat); // modal group 6 // G20-21 or G70-71 var gCycleModal = createOutputVariable({}, gFormat); // modal group 9 // G81, ... var gRetractModal = createOutputVariable({}, gFormat); // modal group 10 // G98-99 var gRotationModal = createOutputVariable({current : 69, onchange: function () { state.twpIsActive = gRotationModal.getCurrent() != 69; if (typeof probeVariables != "undefined") { probeVariables.outputRotationCodes = probeVariables.probeAngleMethod == "G68"; } }}, gFormat); var fourthAxisClamp = createOutputVariable({}, mFormat); var fifthAxisClamp = createOutputVariable({}, mFormat); var sixthAxisClamp = createOutputVariable({}, 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}, {id:COOLANT_THROUGH_TOOL, on:7}, {id:COOLANT_AIR}, {id:COOLANT_AIR_THROUGH_TOOL, on:"M11 Q1", off:"M11 Q0"}, {id:COOLANT_SUCTION}, {id:COOLANT_FLOOD_MIST, on:10}, {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 : undefined, // enter property value id(s) for using "0" value instead of machineConfiguration axes home position values (ie G30 Z0) homeXY : {onIndexing:false, onToolChange:false, onProgramEnd:{axes:[X, Y]}} // Specifies when the machine should be homed in X/Y. Sample: onIndexing:{axes:[X, Y], singleLine:false} }, parametricFeeds: { firstFeedParameter : 1, // specifies the initial parameter number to be used for parametric feedrate output feedAssignmentVariable: "#", // specifies the syntax to define a parameter feedOutputVariable : "F#" // specifies the syntax to output the feedrate as parameter }, machineAngles: { // refer to https://cam.autodesk.com/posts/reference/classMachineConfiguration.html#a14bcc7550639c482492b4ad05b1580c8 controllingAxis: ABC, type : PREFER_PREFERENCE, options : ENABLE_ALL }, workPlaneMethod: { useTiltedWorkplane : true, // specifies that tilted workplanes should be used (ie. G68.2, G254, PLANE SPATIAL, CYCLE800), can be overwritten by property eulerConvention : undefined, // 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 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: " 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 : "ignoreCase", // can be set to "upperCase", "lowerCase" and "ignoreCase". Set to "ignoreCase" to write comments without upper/lower case formatting maximumLineLength : 120 // the maximum number of characters allowed in a line, set to 0 to disable comment output }, probing: { macroCall : gFormat.format(65), // specifies the command to call a macro probeAngleMethod : undefined, // supported options are: OFF, AXIS_ROT, G68, G54.4. 'undefined' uses automatic selection probeAngleVariables : {x:"#135", y:"#136", r:"#144", baseParamG54x4:26000, baseParamAxisRot:5200, method:0}, // specifies variables for the angle compensation macros, method 0 = Fanuc, 1 = Haas allowIndexingWCSProbing: false // specifies that probe WCS with tool orientation is supported }, maximumSequenceNumber : undefined, // the maximum sequence number (Nxxx), use 'undefined' for unlimited maximumToolNumber : 99, // specifies the maximum allowed tool number maximumToolLengthOffset : 200, // specifies the maximum allowed tool length offset number supportsToolVectorOutput: true // specifies if the control does support tool axis vector output for multi axis toolpath }; // fixed settings var useVectorOutput; // useVectorOutput is enabled automatically when no machine configuration is defined 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 settings.outputToolDiameterOffset = getProperty("outputToolDiameterOffset"); settings.outputToolLengthCompensation = getProperty("useG43"); if (getProperty("homeXYonToolChange") != "disabled") { switch (getProperty("homeXYonToolChange")) { case "x": settings.retract.homeXY.onToolChange = {axes:[X]}; break; case "y": settings.retract.homeXY.onToolChange = {axes:[Y]}; break; case "xy": settings.retract.homeXY.onToolChange = {axes:[X, Y]}; break; } } if (!machineConfiguration.isMultiAxisConfiguration() && !tcp.isSupportedByMachine) { tcp.isSupportedByMachine = true; // default to true when no machine configuration is defined } useVectorOutput = !machineConfiguration.isMultiAxisConfiguration(); // set to 'true' to force vector output. This is not recommended and not tested. When forcing vector output, machine simulation will not be accurate. if (useVectorOutput) { settings.workPlaneMethod.eulerConvention = EULER_XYZ_R; // not utilized, but set to avoid errors /* // If no ABC output is desired at all, uncomment the following lines. // Note this is not recommended as it may cause unexpected behavior. aOutput.disable(); bOutput.disable(); cOutput.disable(); */ } if (!getProperty("separateWordsWithSpace")) { setWordSeparator(""); } writeln("%"); writeln("O" + oFormat.format(getProgramNumber()) + conditional(programComment, " " + formatComment(programComment))); writeProgramHeader(); if (typeof inspectionWriteVariables == "function") { inspectionWriteVariables(); } if (!is3D() && (useVectorOutput && machineConfiguration.isMultiAxisConfiguration())) { onCommand(COMMAND_STOP); var msg = "The postprocessor has been modified to use vector output even though a machine configuration has been defined." + EOL + "Be aware that the machine simulation may not be accurate." + EOL + "We also cannot guarantee that the CNC will not have to rewind while cutting when using vector output."; onComment(msg); warning(msg); } for (var i = 0; i < getNumberOfSections(); ++i) { var section = getSection(i); if (!getProperty("outputToolDiameterOffset") && (section.getParameter("operation:compensationType") == "wear" || section.getParameter("operation:compensationType") == "inverseWear")) { error(subst(localize("Wear compensation is not supported when property '%1' is set to 'false'."), properties.outputToolDiameterOffset.title)); return; } } // absolute coordinates and feed per min writeBlock(gAbsIncModal.format(90), gPlaneModal.format(17), gFormat.format(40), gCycleModal.format(80)); if (!getProperty("isnc")) { writeBlock(gAbsIncModal.format(75)); // multi-quadrant arc interpolation mode } switch (unit) { case IN: writeBlock(gUnitModal.format(getProperty("isnc") ? 20 : 70)); break; case MM: writeBlock(gUnitModal.format(getProperty("isnc") ? 21 : 71)); break; } onCommand(COMMAND_START_CHIP_TRANSPORT); if (!is3D() || machineConfiguration.isMultiAxisConfiguration()) { writeBlock(mFormat.format(31)); // rotary axes encoder reset writeBlock(mFormat.format(126)); // shortest path traverse } validateCommonParameters(); } function onSection() { var forceSectionRestart = optionalSection && !currentSection.isOptional(); optionalSection = currentSection.isOptional(); var insertToolCall = isToolChangeNeeded() || 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 } writeRetract(Z); // retract if (isFirstSection()) { cancelWorkPlane(true); if (machineConfiguration.isMultiAxisConfiguration()) { positionABC(new Vector(0, 0, 0), true); } } // Head axes need to return to 0 for tool change if (insertToolCall && !isFirstSection() && machineConfiguration.isHeadConfiguration()) { var resetAxes = getCurrentDirection(); var axes = [machineConfiguration.getAxisU(), machineConfiguration.getAxisV(), machineConfiguration.getAxisW()]; for (var i = 0; i < axes.length; ++i) { if (axes[i].isEnabled() && axes[i].isHead()) { resetAxes.setCoordinate(axes[i].getCoordinate(), 0); } } positionABC(resetAxes, false); } } writeComment(getParameter("operation-comment", "")); if (getProperty("showNotes")) { writeSectionNotes(); } // tool change writeToolCall(tool, insertToolCall); startSpindle(tool, insertToolCall); // write parametric feedrate table if (typeof initializeParametricFeeds == "function") { initializeParametricFeeds(insertToolCall); } if (insertToolCall) { var offsetCode = getOffsetCode(); if (offsetCode) { writeBlock(offsetCode, hFormat.format(tool.lengthOffset)); } if (tool.type == TOOL_PROBE) { if (getProperty("isnc")) { writeBlock(mFormat.format(19)); // spindle orientation writeBlock(mFormat.format(26)); // select the part probe, M27 is selecting the tool probe writeBlock(mFormat.format(41)); // single touch probing, M42 is 2 touch probing } else { error(localize("Probing or Inspection is only allowed in ISNC mode!")); } } } // Output modal commands here writeBlock(gPlaneModal.format(17), gAbsIncModal.format(90), gFeedModeModal.format(94)); // set wcs var wcsIsRequired = true; if (insertToolCall) { currentWorkOffset = undefined; // force work offset when changing tool wcsIsRequired = newWorkOffset || insertToolCall; } writeWCS(currentSection, wcsIsRequired); forceXYZ(); var abc = defineWorkPlane(currentSection, true); setProbeAngle(); // output probe angle rotations if required setCoolant(tool.coolant); // writes the required coolant codes // prepositioning var initialPosition = getFramePosition(currentSection.getInitialPosition()); var isRequired = insertToolCall || state.retractedZ || (!state.tcpIsActive && tcp.isSupportedByOperation) || !state.lengthCompensationActive || (!isFirstSection() && getPreviousSection().isMultiAxis()); writeInitialPositioning(initialPosition, isRequired); if (isProbeOperation()) { validate(probeVariables.probeAngleMethod != "G68", "You cannot probe while G68 Rotation is in effect."); validate(probeVariables.probeAngleMethod != "G54.4", "You cannot probe while workpiece setting error compensation G54.4 is enabled."); // writeBlock(gFormat.format(65), "P" + 9832); // spin the probe on //Probe doesn't need to be activate or de activated, as the controller is doing it automatically at toolchange. inspectionCreateResultsFileHeader(); } if (typeof inspectionProcessSectionStart == "function") { inspectionProcessSectionStart(); } } function writeInitialPositioning(position, isRequired, codes1, codes2) { var motionCode = {single:0, multi:0}; switch (highFeedMapping) { case HIGH_FEED_MAP_ANY: motionCode = {single:1, multi:1}; // map all rapid traversals to high feed break; case HIGH_FEED_MAP_MULTI: motionCode = {single:0, multi:1}; // map rapid traversal along more than one axis to high feed break; } var feed = (highFeedMapping != HIGH_FEED_NO_MAPPING) ? getFeed(highFeedrate) : ""; var additionalCodes = [formatWords(codes1), formatWords(codes2)]; writeStartBlocks(isRequired, function() { var modalCodes = formatWords(gAbsIncModal.format(90), gPlaneModal.format(17)); // multi axis prepositioning if (currentSection.isMultiAxis()) { writeBlock(modalCodes); cancelWorkPlane(); onCommand(COMMAND_UNLOCK_MULTI_AXIS); setTCP(tcp.isSupportedByOperation); var direction = currentSection.isOptimizedForMachine() ? getCurrentDirection().isNonZero() ? getCurrentDirection() : currentSection.getInitialToolAxisABC() : currentSection.getGlobalInitialToolAxis(); writeASR(position, direction); var W = machineConfiguration.isMultiAxisConfiguration() ? machineConfiguration.getOrientation(getCurrentDirection()) : Matrix.getOrientationFromDirection(getCurrentDirection()); var prePosition = W.getTransposed().multiply(position); machineSimulation({x:prePosition.x, y:prePosition.y, mode:machineConfiguration.isHeadConfiguration() ? undefined : TWPON}); // mimic behavior of the ASR feature machineSimulation(tcp.isSupportedByOperation ? {x:position.x, y:position.y, z:position.z} : {z:position.z}); if (tcp.isSupportedByOperation) { writeBlock(gFormat.format(43.4)); } if (!machineConfiguration.isMultiAxisConfiguration()) { writeBlock(mFormat.format(200), "P" + (getProperty("preferredTilt") ? 1 : 2)); // prefer positive/negative tilt } } else { setTCP(tcp.isSupportedByOperation); if (machineConfiguration.isHeadConfiguration()) { writeBlock(modalCodes, gMotionModal.format(motionCode.multi), xOutput.format(position.x), yOutput.format(position.y), zOutput.format(position.z), feed, additionalCodes ); machineSimulation({x:position.x, y:position.y, z:position.z}); } else { writeBlock(modalCodes, gMotionModal.format(motionCode.multi), xOutput.format(position.x), yOutput.format(position.y), feed, additionalCodes[0]); machineSimulation({x:position.x, y:position.y}); writeBlock(gMotionModal.format(motionCode.single), zOutput.format(position.z), additionalCodes[1]); machineSimulation(tcp.isSupportedByOperation ? {x:position.x, y:position.y, z:position.z} : {z:position.z}); } } forceModals(gMotionModal); if (isRequired) { additionalCodes = []; // clear additionalCodes buffer } }); validate(!validateLengthCompensation || state.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)); forceXYZ(); if (!state.retractedZ && xyzFormat.getResultingValue(getCurrentPosition().z) < xyzFormat.getResultingValue(position.z)) { writeBlock(modalCodes, gMotionModal.format(motionCode.single), zOutput.format(position.z), feed); machineSimulation({z:position.z}); } writeBlock(modalCodes, gMotionModal.format(motionCode.multi), xOutput.format(position.x), yOutput.format(position.y), feed, additionalCodes); machineSimulation({x:position.x, y:position.y}); } if (!state.tcpIsActive && isTCPSupportedByOperation(currentSection)) { error(localize("Internal error, TCP is required but was not output by the postprocessor.")); } } var currentWorkPlaneABC = undefined; var currentWorkPlaneUVW = undefined; // right vector from workplane matrix function forceWorkPlane() { currentWorkPlaneABC = undefined; currentWorkPlaneUVW = undefined; } function cancelWorkPlane(force) { if (force) { gRotationModal.reset(); } writeBlock(gRotationModal.format(69)); // cancel frame forceWorkPlane(); } function writeASR(position, direction) { forceXYZ(); forceABC(); writeBlock( gFormat.format(8.2), xOutput.format(position.x), yOutput.format(position.y), zOutput.format(position.z), useVectorOutput ? formatWords("I" + ijkFormat.format(direction.x), "J" + ijkFormat.format(direction.y), "K" + ijkFormat.format(direction.z)) : formatWords(aOutput.format(direction.x), bOutput.format(direction.y), cOutput.format(direction.z)) ); setCurrentPosition(position); forceXYZ(); forceModals(gMotionModal); } function setWorkPlane(abc) { if (!settings.workPlaneMethod.forceMultiAxisIndexing && is3D() && !machineConfiguration.isMultiAxisConfiguration()) { return; // ignore } if (settings.workPlaneMethod.forceMultiAxisIndexing) { forceWorkPlane(); } var W = currentSection.workPlane; var workplaneIsRequired = true; if (machineConfiguration.isMultiAxisConfiguration()) { workplaneIsRequired = (currentWorkPlaneABC == undefined) || abcFormat.areDifferent(abc.x, currentWorkPlaneABC.x) || abcFormat.areDifferent(abc.y, currentWorkPlaneABC.y) || abcFormat.areDifferent(abc.z, currentWorkPlaneABC.z); } else { workplaneIsRequired = (currentWorkPlaneABC == undefined || currentWorkPlaneUVW == undefined) || ijkFormat.areDifferent(W.up.x, currentWorkPlaneABC.x) || ijkFormat.areDifferent(W.up.y, currentWorkPlaneABC.y) || ijkFormat.areDifferent(W.up.z, currentWorkPlaneABC.z) || ijkFormat.areDifferent(W.right.x, currentWorkPlaneUVW.x) || ijkFormat.areDifferent(W.right.y, currentWorkPlaneUVW.y) || ijkFormat.areDifferent(W.right.z, currentWorkPlaneUVW.z); } writeStartBlocks(workplaneIsRequired, function () { state.retractedZ = false; // force retract writeRetract(Z); if (getSetting("retract.homeXY.onIndexing", false)) { writeRetract(settings.retract.homeXY.onIndexing); } if (settings.workPlaneMethod.useTiltedWorkplane) { onCommand(COMMAND_UNLOCK_MULTI_AXIS); cancelWorkPlane(true); // cancel frame 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); } } var initialPosition = getFramePosition(currentSection.getInitialPosition()); var workPlaneCode = 68.2; if (machineConfiguration.getNumberOfAxes() == 5 && machineConfiguration.getAxisU().getCoordinate() > machineConfiguration.getAxisV().getCoordinate()) { workPlaneCode = 68.3; } writeBlock( gRotationModal.format(workPlaneCode), "X" + xyzFormat.format(currentSection.workOrigin.x), "Y" + xyzFormat.format(currentSection.workOrigin.y), "Z" + xyzFormat.format(currentSection.workOrigin.z), useVectorOutput ? formatWords( "I" + ijkFormat.format(W.right.x), "J" + ijkFormat.format(W.right.y), "K" + ijkFormat.format(W.right.z), "U" + ijkFormat.format(W.up.x), "V" + ijkFormat.format(W.up.y), "W" + ijkFormat.format(W.up.z)) : formatWords( 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))) ); // set frame // if (!machineConfiguration.isMultiAxisConfiguration()) { // writeBlock(mFormat.format(200), "P" + (getProperty("preferredTilt") ? 1 : 2)); // prefer positive/negative tilt // } writeASR(initialPosition, useVectorOutput ? currentSection.getInitialToolAxis() : abc); machineSimulation({a:getCurrentABC().x, b:getCurrentABC().y, c:getCurrentABC().z, coordinates:MACHINE}); } else { gMotionModal.reset(); positionABC(abc, true); } if (!currentSection.isMultiAxis()) { onCommand(COMMAND_LOCK_MULTI_AXIS); } if (machineConfiguration.isMultiAxisConfiguration()) { currentWorkPlaneABC = abc; } else { currentWorkPlaneABC = W.up; currentWorkPlaneUVW = W.right; } }); } var toolLengthCompOutput = createOutputVariable({control : CONTROL_FORCE, onchange: function() { state.lengthCompensationActive = toolLengthCompOutput.getCurrent() != 49; } }, gFormat); function getOffsetCode() { if (!getSetting("outputToolLengthCompensation", true) && toolLengthCompOutput.isEnabled()) { state.lengthCompensationActive = true; // always assume that length compensation is active toolLengthCompOutput.disable(); } var offsetCode = 43; return toolLengthCompOutput.format(offsetCode); } 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 abc = new Vector(_a, _b, _c); if (currentSection.isOptimizedForMachine() && useVectorOutput) { abc = machineConfiguration.getDirection(new Vector(_a, _b, _c)); } var a = currentSection.isOptimizedForMachine() && !useVectorOutput ? aOutput.format(abc.x) : toolVectorOutputI.format(abc.x); var b = currentSection.isOptimizedForMachine() && !useVectorOutput ? bOutput.format(abc.y) : toolVectorOutputJ.format(abc.y); var c = currentSection.isOptimizedForMachine() && !useVectorOutput ? cOutput.format(abc.z) : toolVectorOutputK.format(abc.z); if (x || y || z || a || b || c) { writeBlock(gMotionModal.format(0), x, y, z, a, b, c); forceFeed(); } } 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 abc = new Vector(_a, _b, _c); if (currentSection.isOptimizedForMachine() && useVectorOutput) { abc = machineConfiguration.getDirection(new Vector(_a, _b, _c)); } var a = currentSection.isOptimizedForMachine() && !useVectorOutput ? aOutput.format(abc.x) : toolVectorOutputI.format(abc.x); var b = currentSection.isOptimizedForMachine() && !useVectorOutput ? bOutput.format(abc.y) : toolVectorOutputJ.format(abc.y); var c = currentSection.isOptimizedForMachine() && !useVectorOutput ? cOutput.format(abc.z) : toolVectorOutputK.format(abc.z); 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); } } } function setTCP(_tcp, force) { if (!force) { if (!tcp.isSupportedByMachine || state.tcpIsActive == _tcp) { return; } } var tcpCode = mFormat.format(_tcp ? 128 : 129); state.tcpIsActive = _tcp; writeBlock(tcpCode); } function onDwell(seconds) { var maxValue = 9999.999; if (seconds > maxValue) { warning(subst(localize("Dwelling time of '%1' exceeds the maximum value of '%2' in operation '%3'"), seconds, maxValue, getParameter("operation-comment", ""))); } seconds = clamp(0.001, seconds, maxValue); writeBlock(gFeedModeModal.format(94), gFormat.format(4), "P" + secFormat.format(seconds)); } function onSpindleSpeed(spindleSpeed) { writeBlock(sOutput.format(spindleSpeed)); } function onCycle() { writeBlock(gPlaneModal.format(17)); } function getCommonCycle(x, y, z, r) { forceXYZ(); if (getProperty("isnc")) { return [xOutput.format(x), yOutput.format(y), zOutput.format(z), "R" + xyzFormat.format(r)]; } else { return [xOutput.format(x), yOutput.format(y), "Z" + xyzFormat.format(z), "R" + xyzFormat.format(r)]; } } function onCyclePoint(x, y, z) { if (isInspectionOperation()) { if (typeof inspectionCycleInspect == "function") { inspectionCycleInspect(cycle, x, y, z); return; } else { cycleNotSupported(); } } else if (isProbeOperation()) { writeProbeCycle(cycle, x, y, z); } else { writeDrillCycle(cycle, x, y, z); } } function writeDrillCycle(cycle, x, y, z) { if (!isSameDirection(machineConfiguration.getSpindleAxis(), getForwardDirection(currentSection))) { expandCyclePoint(x, y, z); return; } if (isFirstCyclePoint()) { // return to initial Z which is clearance plane and set absolute mode repositionToCycleClearance(cycle, x, y, z); // R is only used in G99 mode for BNC var F = cycle.feedrate; var P = !cycle.dwell ? 0 : clamp(1, cycle.dwell, 9999.999); // in seconds switch (cycleType) { case "drilling": if (getProperty("isnc")) { writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(81), getCommonCycle(x, y, z, cycle.retract), feedOutput.format(F) ); } else { // BNC mode writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(81), getCommonCycle(x, y, cycle.clearance - cycle.bottom, zOutput.getCurrent() - cycle.retract), feedOutput.format(F) ); } break; case "counter-boring": if (P > 0) { if (getProperty("isnc")) { writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(82), getCommonCycle(x, y, z, cycle.retract), "P" + secFormat.format(P), // not optional feedOutput.format(F) ); } else { // BNC mode writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(82), getCommonCycle(x, y, cycle.clearance - cycle.bottom, zOutput.getCurrent() - cycle.retract), "P" + secFormat.format(P), // not optional feedOutput.format(F) ); } } else { if (getProperty("isnc")) { writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(81), getCommonCycle(x, y, z, cycle.retract), feedOutput.format(F) ); } else { // BNC mode writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(81), getCommonCycle(x, y, cycle.clearance - cycle.bottom, zOutput.getCurrent() - cycle.retract), feedOutput.format(F) ); } } break; case "chip-breaking": if ((cycle.accumulatedDepth < cycle.depth) || (P > 0)) { expandCyclePoint(x, y, z); } else { if (getProperty("isnc")) { writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(73), getCommonCycle(x, y, z, cycle.retract), "Q" + xyzFormat.format(cycle.incrementalDepth), feedOutput.format(F) ); } else { // BNC mode writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(73), getCommonCycle(x, y, cycle.clearance - cycle.bottom, zOutput.getCurrent() - cycle.retract), "Q" + xyzFormat.format(cycle.incrementalDepth), feedOutput.format(F) ); } } break; case "deep-drilling": if (P > 0) { expandCyclePoint(x, y, z); } else { if (getProperty("isnc")) { writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(83), getCommonCycle(x, y, z, cycle.retract), "Q" + xyzFormat.format(cycle.incrementalDepth), feedOutput.format(F) ); } else { // BNC mode writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(83), xOutput.format(x), yOutput.format(y), "Z" + xyzFormat.format(cycle.clearance - cycle.bottom), "Z" + xyzFormat.format(cycle.incrementalDepth), // first peck conditional((cycle.minimumIncrementalDepth != undefined) && (cycle.minimumIncrementalDepth < cycle.incrementalDepth), "Z" + xyzFormat.format(cycle.minimumIncrementalDepth)), // remaining pecks "R" + xyzFormat.format(zOutput.getCurrent() - cycle.retract), feedOutput.format(F) ); } } break; case "tapping": if (true || !F) { F = tool.getTappingFeedrate(); } if (getProperty("isnc")) { writeBlock(mFormat.format(29)); // rigid writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format((tool.type == TOOL_TAP_LEFT_HAND) ? 74 : 84), getCommonCycle(x, y, z, cycle.retract), "P" + secFormat.format(P), // not optional feedOutput.format(F) ); } else { // BNC mode if (tool.type != TOOL_TAP_LEFT_HAND) { // right hand writeBlock(mFormat.format(3)); // cw writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(88), // rigid xOutput.format(x), yOutput.format(y), "Z" + xyzFormat.format(cycle.clearance - cycle.bottom), //"Z" + xyzFormat.format(cycle.incrementalDepth), "R" + xyzFormat.format(zOutput.getCurrent() - cycle.retract), "P" + secFormat.format(P), // not optional feedOutput.format(F) ); if (!tool.clockwise) { writeBlock(mFormat.format(tool.clockwise ? 3 : 4)); } } else { // left hand // warning: not rigid writeBlock(mFormat.format((tool.type == TOOL_TAP_LEFT_HAND) ? 4 : 3)); writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(84), getCommonCycle(x, y, cycle.clearance - cycle.bottom, zOutput.getCurrent() - cycle.retract), feedOutput.format(F) ); if ((tool.type == TOOL_TAP_LEFT_HAND) != !tool.clockwise) { writeBlock(mFormat.format(tool.clockwise ? 3 : 4)); } } } break; case "left-tapping": if (true || !F) { F = tool.getTappingFeedrate(); } if (getProperty("isnc")) { writeBlock(mFormat.format(29)); // rigid writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(74), getCommonCycle(x, y, z, cycle.retract), "P" + secFormat.format(P), // not optional feedOutput.format(F) ); } else { // BNC mode // warning: not rigid writeBlock(mFormat.format(4)); // ccw writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(84), getCommonCycle(x, y, cycle.clearance - cycle.bottom, zOutput.getCurrent() - cycle.retract), feedOutput.format(F) ); if (tool.clockwise) { writeBlock(mFormat.format(tool.clockwise ? 3 : 4)); } } break; case "right-tapping": if (true || !F) { F = tool.getTappingFeedrate(); } if (getProperty("isnc")) { writeBlock(mFormat.format(29)); // rigid writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(84), getCommonCycle(x, y, z, cycle.retract), "P" + secFormat.format(P), // not optional feedOutput.format(F) ); } else { // BNC mode writeBlock(mFormat.format(3)); // cw writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(88), // rigid xOutput.format(x), yOutput.format(y), "Z" + xyzFormat.format(cycle.clearance - cycle.bottom), "R" + xyzFormat.format(zOutput.getCurrent() - cycle.retract), "P" + secFormat.format(P), // not optional feedOutput.format(F) ); if (!tool.clockwise) { writeBlock(mFormat.format(tool.clockwise ? 3 : 4)); } } break; case "tapping-with-chip-breaking": case "left-tapping-with-chip-breaking": case "right-tapping-with-chip-breaking": if (cycle.accumulatedDepth < cycle.depth) { error(localize("Accumulated pecking depth is not supported for canned tapping cycles with chip breaking.")); return; } if (true || !F) { F = tool.getTappingFeedrate(); } if (getProperty("isnc")) { forceXYZ(); writeBlock(mFormat.format(29)); // rigid writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format((tool.type == TOOL_TAP_LEFT_HAND) ? 84.3 : 84.2), // getCommonCycle(x, y, z, cycle.retract), xOutput.format(x), yOutput.format(y), "Z" + xyzFormat.format(z), "Z" + xyzFormat.format(cycle.incrementalDepth), "R" + xyzFormat.format(cycle.retract), "P" + secFormat.format(P), // not optional conditional(cycle.minimumIncrementalDepth < cycle.depth, "Q" + xyzFormat.format(cycle.minimumIncrementalDepth)), // optional feedOutput.format(F) ); zOutput.reset(); } else { // BNC mode if (tool.type != TOOL_TAP_LEFT_HAND) { // right hand writeBlock(mFormat.format(3)); // cw writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(88), // rigid xOutput.format(x), yOutput.format(y), "Z" + xyzFormat.format(cycle.clearance - cycle.bottom), "Z" + xyzFormat.format(cycle.incrementalDepth), "R" + xyzFormat.format(zOutput.getCurrent() - cycle.retract), "P" + secFormat.format(P), // not optional feedOutput.format(F) ); if (!tool.clockwise) { writeBlock(mFormat.format(tool.clockwise ? 3 : 4)); } } else { error(localize("Left-tapping with chip breaking is not supported.")); } } break; case "fine-boring": if (getProperty("isnc")) { writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(76), getCommonCycle(x, y, z, cycle.retract), "P" + secFormat.format(P), // not optional "Q" + xyzFormat.format(cycle.shift), feedOutput.format(F) ); } else { // BNC mode writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(76), getCommonCycle(x, y, cycle.clearance - cycle.bottom, zOutput.getCurrent() - cycle.retract), "P" + secFormat.format(P), // not optional "Q" + xyzFormat.format(cycle.shift), feedOutput.format(F) ); } break; case "back-boring": if (!getProperty("isnc")) { error(localize("Back boring is not supported.")); } var dx = (gPlaneModal.getCurrent() == 19) ? cycle.backBoreDistance : 0; var dy = (gPlaneModal.getCurrent() == 18) ? cycle.backBoreDistance : 0; var dz = (gPlaneModal.getCurrent() == 17) ? cycle.backBoreDistance : 0; writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(87), getCommonCycle(x - dx, y - dy, z - dz, cycle.bottom), "Q" + xyzFormat.format(cycle.shift), "P" + secFormat.format(P), // not optional feedOutput.format(F) ); break; case "reaming": if (feedFormat.getResultingValue(cycle.feedrate) != feedFormat.getResultingValue(cycle.retractFeedrate)) { expandCyclePoint(x, y, z); break; } if (getProperty("isnc")) { writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(85), getCommonCycle(x, y, z, cycle.retract), feedOutput.format(F) ); } else { // BNC mode writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(85), getCommonCycle(x, y, cycle.clearance - cycle.bottom, zOutput.getCurrent() - cycle.retract), feedOutput.format(F) ); } break; case "stop-boring": if ((P > 0) || !getProperty("isnc")) { expandCyclePoint(x, y, z); } else { writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(86), getCommonCycle(x, y, z, cycle.retract), feedOutput.format(F) ); } break; case "manual-boring": if (!getProperty("isnc")) { error(localize("Manual boring is not supported.")); } writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(88), getCommonCycle(x, y, z, cycle.retract), "P" + secFormat.format(P), // not optional feedOutput.format(F) ); break; case "boring": if (feedFormat.getResultingValue(cycle.feedrate) != feedFormat.getResultingValue(cycle.retractFeedrate)) { expandCyclePoint(x, y, z); break; } if (getProperty("isnc")) { writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(89), getCommonCycle(x, y, z, cycle.retract), "P" + secFormat.format(P), // not optional feedOutput.format(F) ); } else { // BNC writeBlock( gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(89), getCommonCycle(x, y, cycle.clearance - cycle.bottom, zOutput.getCurrent() - cycle.retract), "P" + secFormat.format(P), // not optional feedOutput.format(F) ); } break; default: expandCyclePoint(x, y, z); } } else { if (cycleExpanded) { expandCyclePoint(x, y, z); } else { var _x = xOutput.format(x); var _y = yOutput.format(y); if (!_x && !_y) { xOutput.reset(); // at least one axis is required _x = xOutput.format(x); } writeBlock(_x, _y); } } } function onCycleEnd() { if (isProbeOperation()) { zOutput.reset(); gMotionModal.reset(); writeBlock(gFormat.format(65), "P" + 9810, zOutput.format(cycle.retract)); // protected retract move } else { if (!cycleExpanded) { writeBlock(gCycleModal.format(80)); zOutput.reset(); } } } function onCircular(clockwise, cx, cy, cz, x, y, z, feed) { if (pendingRadiusCompensation >= 0) { error(localize("Radius compensation cannot be activated/deactivated for a circular move.")); return; } var start = getCurrentPosition(); if (isFullCircle()) { if (isHelical()) { linearize(tolerance); return; } switch (getCircularPlane()) { case PLANE_XY: if (getProperty("isnc")) { writeBlock(gAbsIncModal.format(90), gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), irOutput.format(cx - start.x), jrOutput.format(cy - start.y), getFeed(feed)); } else { writeBlock(gAbsIncModal.format(90), gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), iOutput.format(cx), jOutput.format(cy), getFeed(feed)); } break; case PLANE_ZX: if (getProperty("isnc")) { // right-handed writeBlock(gAbsIncModal.format(90), gPlaneModal.format(18), gMotionModal.format(clockwise ? 2 : 3), irOutput.format(cx - start.x), krOutput.format(cz - start.z), getFeed(feed)); } else { // note: left hand coordinate system writeBlock(gAbsIncModal.format(90), gPlaneModal.format(18), gMotionModal.format(clockwise ? 3 : 2), iOutput.format(cx), kOutput.format(cz), getFeed(feed)); } break; case PLANE_YZ: if (getProperty("isnc")) { writeBlock(gAbsIncModal.format(90), gPlaneModal.format(19), gMotionModal.format(clockwise ? 2 : 3), jrOutput.format(cy - start.y), krOutput.format(cz - start.z), getFeed(feed)); } else { writeBlock(gAbsIncModal.format(90), gPlaneModal.format(19), gMotionModal.format(clockwise ? 2 : 3), jOutput.format(cy), kOutput.format(cz), getFeed(feed)); } break; default: linearize(tolerance); } } else { switch (getCircularPlane()) { case PLANE_XY: if (getProperty("isnc")) { writeBlock(gAbsIncModal.format(90), gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), irOutput.format(cx - start.x), jrOutput.format(cy - start.y), getFeed(feed)); } else { writeBlock(gAbsIncModal.format(90), gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), iOutput.format(cx), jOutput.format(cy), getFeed(feed)); } break; case PLANE_ZX: if (isHelical()) { linearize(tolerance); return; } if (getProperty("isnc")) { writeBlock(gAbsIncModal.format(90), gPlaneModal.format(18), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), irOutput.format(cx - start.x), krOutput.format(cz - start.z), getFeed(feed)); } else { // note: left hand coordinate system writeBlock(gAbsIncModal.format(90), gPlaneModal.format(18), gMotionModal.format(clockwise ? 3 : 2), xOutput.format(x), yOutput.format(y), zOutput.format(z), iOutput.format(cx), kOutput.format(cz), getFeed(feed)); } break; case PLANE_YZ: if (isHelical()) { linearize(tolerance); return; } if (getProperty("isnc")) { writeBlock(gAbsIncModal.format(90), gPlaneModal.format(19), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), jrOutput.format(cy - start.y), krOutput.format(cz - start.z), getFeed(feed)); } else { writeBlock(gAbsIncModal.format(90), gPlaneModal.format(19), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), jOutput.format(cy), kOutput.format(cz), getFeed(feed)); } break; default: if (getProperty("allow3DArcs")) { // make sure maximumCircularSweep is well below 360deg // we could use G2.4 or G3.4 - direction is calculated var ip = getPositionU(0.5); writeBlock(gAbsIncModal.format(90), gMotionModal.format(clockwise ? 2.4 : 3.4), xOutput.format(ip.x), yOutput.format(ip.y), zOutput.format(ip.z)); writeBlock(xOutput.format(x), yOutput.format(y), zOutput.format(z), getFeed(feed)); } else { linearize(tolerance); } } } } var mapCommand = { COMMAND_END : 2, COMMAND_SPINDLE_CLOCKWISE : 3, COMMAND_SPINDLE_COUNTERCLOCKWISE: 4, 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; forceCoolant = true; return; case COMMAND_OPTIONAL_STOP: writeBlock(mFormat.format(1)); forceSpindleSpeed = true; forceCoolant = true; return; case COMMAND_START_SPINDLE: forceSpindleSpeed = false; writeBlock(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: if (machineConfiguration.isMachineCoordinate(0) || !machineConfiguration.isMultiAxisConfiguration()) { writeBlock(fourthAxisClamp.format(32)); // A-axis } if (machineConfiguration.isMachineCoordinate(1) || !machineConfiguration.isMultiAxisConfiguration()) { writeBlock(fifthAxisClamp.format(34)); // B-axis } if (machineConfiguration.isMachineCoordinate(2) || !machineConfiguration.isMultiAxisConfiguration()) { writeBlock(sixthAxisClamp.format(12)); // C-axis } return; case COMMAND_UNLOCK_MULTI_AXIS: if (machineConfiguration.isMachineCoordinate(0) || !machineConfiguration.isMultiAxisConfiguration()) { writeBlock(fourthAxisClamp.format(33)); // A-axis } if (machineConfiguration.isMachineCoordinate(1) || !machineConfiguration.isMultiAxisConfiguration()) { writeBlock(fifthAxisClamp.format(35)); // B-axis } if (machineConfiguration.isMachineCoordinate(2) || !machineConfiguration.isMultiAxisConfiguration()) { writeBlock(sixthAxisClamp.format(13)); // C-axis } return; case COMMAND_START_CHIP_TRANSPORT: writeBlock(mFormat.format(59)); return; case COMMAND_STOP_CHIP_TRANSPORT: writeBlock(mFormat.format(61)); return; case COMMAND_BREAK_CONTROL: return; case COMMAND_TOOL_MEASURE: return; case COMMAND_PROBE_ON: return; case COMMAND_PROBE_OFF: return; } var stringId = getCommandStringId(command); var mcode = mapCommand[stringId]; if (mcode != undefined) { writeBlock(mFormat.format(mcode)); } else { onUnsupportedCommand(command); } } function onSectionEnd() { if (currentSection.isMultiAxis()) { writeBlock(gFeedModeModal.format(94)); // inverse time feed off setTCP(false); if (!isLastSection()) { writeBlock(mFormat.format(31)); // rotary axes encoder reset } } writeBlock(gPlaneModal.format(17)); if (!isLastSection()) { if (getNextSection().getTool().coolant != tool.coolant) { setCoolant(COOLANT_OFF); } if (tool.breakControl && isToolChangeNeeded(getNextSection(), getProperty("toolAsName") ? "description" : "number")) { onCommand(COMMAND_BREAK_CONTROL); } } if (isProbeOperation()) { // writeBlock(gFormat.format(65), "P" + 9833); // spin the probe off //Probe doesn't need to be activate or de activated, as the controller is doing it automatically at toolchange. if (probeVariables.probeAngleMethod != "G68") { setProbeAngle(); // output probe angle rotations if required } } if (typeof inspectionProcessSectionEnd == "function") { inspectionProcessSectionEnd(); } forceAny(); } function writeRetract() { var retract = getRetractParameters.apply(this, arguments); if (retract && retract.words.length > 0) { for (var i in retract.words) { var words = retract.singleLine ? retract.words : retract.words[i]; switch (retract.method) { case "G28": forceModals(gMotionModal, gAbsIncModal); writeBlock(gFormat.format(28), gAbsIncModal.format(91), words); writeBlock(gAbsIncModal.format(90)); break; case "G53": forceModals(gMotionModal); if (retract.retractAxes[2] && getProperty("useM140")) { writeBlock(gFormat.format(0), mFormat.format(140)); } else { writeBlock(gAbsIncModal.format(90), gFormat.format(53), gMotionModal.format(0), words); } break; default: error(subst(localize("Unsupported safe position method '%1'"), retract.method)); } machineSimulation({ x : retract.singleLine || words.indexOf("X") != -1 ? retract.positions.x : undefined, y : retract.singleLine || words.indexOf("Y") != -1 ? retract.positions.y : undefined, z : retract.singleLine || words.indexOf("Z") != -1 ? retract.positions.z : undefined, coordinates: MACHINE }); if (retract.singleLine) { break; } } } } // Start of onRewindMachine logic /** Allow user to override the onRewind logic. */ function onRewindMachineEntry(_a, _b, _c) { if (useVectorOutput) { return true; // skip rewinds when using vector output } return false; } /** Retract to safe position before indexing rotaries. */ function onMoveToSafeRetractPosition() { writeRetract(Z); // cancel TCP so that tool doesn't follow rotaries setTCP(false); } /** Rotate axes to new position above reentry position */ function onRotateAxes(_x, _y, _z, _a, _b, _c) { // position rotary axes xOutput.disable(); yOutput.disable(); zOutput.disable(); onRapid5D(_x, _y, _z, _a, _b, _c); setCurrentABC(new Vector(_a, _b, _c)); machineSimulation({a:_a, b:_b, c:_c, coordinates:MACHINE}); xOutput.enable(); yOutput.enable(); zOutput.enable(); } /** Return from safe position after indexing rotaries. */ function onReturnFromSafeRetractPosition(_x, _y, _z) { // reinstate TCP / tool length compensation if (tcp.isSupportedByOperation) { writeInitialPositioning(new Vector(_x, _y, _z), true); } else { // position in XY forceXYZ(); xOutput.reset(); yOutput.reset(); zOutput.disable(); if (highFeedMapping != HIGH_FEED_NO_MAPPING) { onLinear(_x, _y, _z, highFeedrate); } else { onRapid(_x, _y, _z); } machineSimulation({x:_x, y:_y}); // position in Z zOutput.enable(); invokeOnRapid(_x, _y, _z); } } // End of onRewindMachine logic function onClose() { optionalSection = false; if (isDPRNTopen) { writeln("DPRNT[END]"); writeBlock("PCLOS"); isDPRNTopen = false; } if (probeVariables.probeAngleMethod == "G68") { cancelWorkPlane(); } onCommand(COMMAND_COOLANT_OFF); cancelWorkPlane(); writeRetract(Z); if (machineConfiguration.isMultiAxisConfiguration()) { writeBlock(mFormat.format(31)); // rotary axes encoder reset positionABC(new Vector(0, 0, 0), true); } if (!is3D() || machineConfiguration.isMultiAxisConfiguration()) { writeBlock(mFormat.format(127)); // cancel shortest path traverse } if (getSetting("retract.homeXY.onProgramEnd", false)) { writeRetract(settings.retract.homeXY.onProgramEnd); } if (typeof inspectionProcessSectionEnd == "function") { inspectionProcessSectionEnd(); } onCommand(COMMAND_STOP_CHIP_TRANSPORT); writeBlock(mFormat.format(2)); // end of program, stop spindle, coolant off writeln("E"); } // >>>>> 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 (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 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; // only used for debugging var isTcpOn; // only used for debugging /** * 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 < 50075 || skipBlocks) { return; // return when post kernel revision is lower than 50075 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 = false; var enableTWP = false; if (mode === TCPON) { enableTCP = true; } else if (mode === TCPOFF) { enableTWP = typeof state !== "undefined" && state.twpIsActive; } else if (mode === TWPON) { enableTWP = true; } else if (mode === TWPOFF) { enableTCP = typeof state !== "undefined" && state.tcpIsActive; } else { enableTCP = typeof state !== "undefined" && state.tcpIsActive; enableTWP = typeof state !== "undefined" && state.twpIsActive; } var disableTCP = !enableTCP; var disableTWP = !enableTWP; // update TCP mode if (enableTCP) { simulation.setTWPModeOff(); simulation.setTCPModeOn(); isTwpOn = false; isTcpOn = true; } if (disableTCP) { simulation.setTCPModeOff(); isTcpOn = false; } // update TWP mode if (enableTWP) { simulation.setTCPModeOff(); if (settings.workPlaneMethod.eulerConvention == undefined) { simulation.setTWPModeAlignToCurrentPose(); } else if (eulerAngles) { simulation.setTWPModeByEulerAngles(settings.workPlaneMethod.eulerConvention, eulerAngles.x, eulerAngles.y, eulerAngles.z); } isTwpOn = true; isTcpOn = false; } if (disableTWP) { simulation.setTWPModeOff(); isTwpOn = false; } 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/defineMachine.cpi 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(); 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 || 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/positionABC.cpi function positionABC(abc, force) { if (!machineConfiguration.isMultiAxisConfiguration()) { error("Function 'positionABC' can only be used with multi-axis machine configurations."); } if (typeof unwindABC == "function") { unwindABC(abc); } 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(Z); if (getSetting("retract.homeXY.onIndexing", false)) { writeRetract(settings.retract.homeXY.onIndexing); } onCommand(COMMAND_UNLOCK_MULTI_AXIS); gMotionModal.reset(); writeBlock(gMotionModal.format(0), a, b, c); setCurrentABC(abc); // required for machine simulation machineSimulation({a:abc.x, b:abc.y, c:abc.z, coordinates:MACHINE}); } } // <<<<< 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 (!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/parametricFeeds.cpi properties.useParametricFeed = { title : "Parametric feed", description: "Specifies that the feedrates should be output using parameters.", group : "preferences", type : "boolean", value : false, scope : "post" }; var activeMovements; var currentFeedId; validate(settings.parametricFeeds, "Setting 'parametricFeeds' is required but not defined."); function initializeParametricFeeds(insertToolCall) { if (getProperty("useParametricFeed") && getParameter("operation-strategy") != "drill" && !currentSection.hasAnyCycle()) { if (!insertToolCall && activeMovements && (getCurrentSectionId() > 0) && ((getPreviousSection().getPatternId() == currentSection.getPatternId()) && (currentSection.getPatternId() != 0))) { return; // use the current feeds } } else { activeMovements = undefined; return; } activeMovements = new Array(); var movements = currentSection.getMovements(); var id = 0; var activeFeeds = new Array(); if (hasParameter("operation:tool_feedCutting")) { if (movements & ((1 << MOVEMENT_CUTTING) | (1 << MOVEMENT_LINK_TRANSITION) | (1 << MOVEMENT_EXTENDED))) { var feedContext = new FeedContext(id, localize("Cutting"), getParameter("operation:tool_feedCutting")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_CUTTING] = feedContext; if (!hasParameter("operation:tool_feedTransition")) { activeMovements[MOVEMENT_LINK_TRANSITION] = feedContext; } activeMovements[MOVEMENT_EXTENDED] = feedContext; } ++id; if (movements & (1 << MOVEMENT_PREDRILL)) { feedContext = new FeedContext(id, localize("Predrilling"), getParameter("operation:tool_feedCutting")); activeMovements[MOVEMENT_PREDRILL] = feedContext; activeFeeds.push(feedContext); } ++id; } if (hasParameter("operation:finishFeedrate")) { if (movements & (1 << MOVEMENT_FINISH_CUTTING)) { var feedContext = new FeedContext(id, localize("Finish"), getParameter("operation:finishFeedrate")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_FINISH_CUTTING] = feedContext; } ++id; } else if (hasParameter("operation:tool_feedCutting")) { if (movements & (1 << MOVEMENT_FINISH_CUTTING)) { var feedContext = new FeedContext(id, localize("Finish"), getParameter("operation:tool_feedCutting")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_FINISH_CUTTING] = feedContext; } ++id; } if (hasParameter("operation:tool_feedEntry")) { if (movements & (1 << MOVEMENT_LEAD_IN)) { var feedContext = new FeedContext(id, localize("Entry"), getParameter("operation:tool_feedEntry")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_LEAD_IN] = feedContext; } ++id; } if (hasParameter("operation:tool_feedExit")) { if (movements & (1 << MOVEMENT_LEAD_OUT)) { var feedContext = new FeedContext(id, localize("Exit"), getParameter("operation:tool_feedExit")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_LEAD_OUT] = feedContext; } ++id; } if (hasParameter("operation:noEngagementFeedrate")) { if (movements & (1 << MOVEMENT_LINK_DIRECT)) { var feedContext = new FeedContext(id, localize("Direct"), getParameter("operation:noEngagementFeedrate")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_LINK_DIRECT] = feedContext; } ++id; } else if (hasParameter("operation:tool_feedCutting") && hasParameter("operation:tool_feedEntry") && hasParameter("operation:tool_feedExit")) { if (movements & (1 << MOVEMENT_LINK_DIRECT)) { var feedContext = new FeedContext(id, localize("Direct"), Math.max(getParameter("operation:tool_feedCutting"), getParameter("operation:tool_feedEntry"), getParameter("operation:tool_feedExit"))); activeFeeds.push(feedContext); activeMovements[MOVEMENT_LINK_DIRECT] = feedContext; } ++id; } if (hasParameter("operation:reducedFeedrate")) { if (movements & (1 << MOVEMENT_REDUCED)) { var feedContext = new FeedContext(id, localize("Reduced"), getParameter("operation:reducedFeedrate")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_REDUCED] = feedContext; } ++id; } if (hasParameter("operation:tool_feedRamp")) { if (movements & ((1 << MOVEMENT_RAMP) | (1 << MOVEMENT_RAMP_HELIX) | (1 << MOVEMENT_RAMP_PROFILE) | (1 << MOVEMENT_RAMP_ZIG_ZAG))) { var feedContext = new FeedContext(id, localize("Ramping"), getParameter("operation:tool_feedRamp")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_RAMP] = feedContext; activeMovements[MOVEMENT_RAMP_HELIX] = feedContext; activeMovements[MOVEMENT_RAMP_PROFILE] = feedContext; activeMovements[MOVEMENT_RAMP_ZIG_ZAG] = feedContext; } ++id; } if (hasParameter("operation:tool_feedPlunge")) { if (movements & (1 << MOVEMENT_PLUNGE)) { var feedContext = new FeedContext(id, localize("Plunge"), getParameter("operation:tool_feedPlunge")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_PLUNGE] = feedContext; } ++id; } if (true) { // high feed if ((movements & (1 << MOVEMENT_HIGH_FEED)) || (highFeedMapping != HIGH_FEED_NO_MAPPING)) { var feed; if (hasParameter("operation:highFeedrateMode") && getParameter("operation:highFeedrateMode") != "disabled") { feed = getParameter("operation:highFeedrate"); } else { feed = this.highFeedrate; } var feedContext = new FeedContext(id, localize("High Feed"), feed); activeFeeds.push(feedContext); activeMovements[MOVEMENT_HIGH_FEED] = feedContext; activeMovements[MOVEMENT_RAPID] = feedContext; } ++id; } if (hasParameter("operation:tool_feedTransition")) { if (movements & (1 << MOVEMENT_LINK_TRANSITION)) { var feedContext = new FeedContext(id, localize("Transition"), getParameter("operation:tool_feedTransition")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_LINK_TRANSITION] = feedContext; } ++id; } for (var i = 0; i < activeFeeds.length; ++i) { var feedContext = activeFeeds[i]; var feedDescription = typeof formatComment == "function" ? formatComment(feedContext.description) : feedContext.description; writeBlock(settings.parametricFeeds.feedAssignmentVariable + (settings.parametricFeeds.firstFeedParameter + feedContext.id) + "=" + feedFormat.format(feedContext.feed) + SP + feedDescription); } } function FeedContext(id, description, feed) { this.id = id; this.description = description; this.feed = feed; } // <<<<< INCLUDED FROM include_files/parametricFeeds.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) { if (!getProperty("useCoolant", true)) { return undefined; // coolant output is disabled by property if it exists } 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 properties.writeMachine = { title : "Write machine", description: "Output the machine settings in the header of the program.", group : "formats", type : "boolean", value : true, scope : "post" }; properties.writeTools = { title : "Write tool list", description: "Output a tool list in the header of the program.", group : "formats", type : "boolean", value : true, scope : "post" }; 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 = (getProperty("toolAsName") ? "\"" + tool.description.toUpperCase() + "\"" : "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/onLinear_fanuc.cpi function onLinear(_x, _y, _z, feed) { if (pendingRadiusCompensation >= 0) { xOutput.reset(); yOutput.reset(); } var x = xOutput.format(_x); var y = yOutput.format(_y); var z = zOutput.format(_z); var f = getFeed(feed); if (x || y || z) { if (pendingRadiusCompensation >= 0) { pendingRadiusCompensation = -1; var d = getSetting("outputToolDiameterOffset", true) ? diameterOffsetFormat.format(tool.diameterOffset) : ""; writeBlock(gPlaneModal.format(17)); switch (radiusCompensation) { case RADIUS_COMPENSATION_LEFT: writeBlock(gMotionModal.format(1), gFormat.format(41), x, y, z, d, f); break; case RADIUS_COMPENSATION_RIGHT: writeBlock(gMotionModal.format(1), gFormat.format(42), x, y, z, d, f); break; default: writeBlock(gMotionModal.format(1), gFormat.format(40), x, y, z, f); } } else { writeBlock(gMotionModal.format(1), x, y, z, f); } } else if (f) { if (getNextRecord().isMotion()) { // try not to output feed without motion forceFeed(); // force feed on next line } else { writeBlock(gMotionModal.format(1), f); } } } // <<<<< INCLUDED FROM include_files/onLinear_fanuc.cpi // >>>>> INCLUDED FROM include_files/getProgramNumber_fanuc.cpi function getProgramNumber() { if (typeof oFormat != "undefined" && getProperty("o8")) { oFormat.setMinDigitsLeft(8); } var minimumProgramNumber = getSetting("programNumber.min", 1); var maximumProgramNumber = getSetting("programNumber.max", getProperty("o8") ? 99999999 : 9999); var reservedProgramNumbers = getSetting("programNumber.reserved", [8000, 9999]); if (programName) { var _programNumber; try { _programNumber = getAsInt(programName); } catch (e) { error(localize("Program name must be a number.")); } if (!((_programNumber >= minimumProgramNumber) && (_programNumber <= maximumProgramNumber))) { error(subst(localize("Program number '%1' is out of range. Please enter a program number between '%2' and '%3'."), _programNumber, minimumProgramNumber, maximumProgramNumber)); } if ((_programNumber >= reservedProgramNumbers[0]) && (_programNumber <= reservedProgramNumbers[1])) { warning(subst(localize("Program number '%1' is potentially reserved by the machine tool builder. Reserved range is '%2' to '%3'."), _programNumber, reservedProgramNumbers[0], reservedProgramNumbers[1])); } } else { error(localize("Program name has not been specified.")); } return _programNumber; } // <<<<< INCLUDED FROM include_files/getProgramNumber_fanuc.cpi // >>>>> INCLUDED FROM include_files/commonInspectionFunctions_fanuc.cpi var macroFormat = createFormat({prefix:(typeof inspectionVariables == "undefined" ? "#" : inspectionVariables.localVariablePrefix), decimals:0}); var macroRoundingFormat = (unit == MM) ? "[53]" : "[44]"; var isDPRNTopen = false; var WARNING_OUTDATED = 0; var toolpathIdFormat = createFormat({decimals:5, forceDecimal:true}); var patternInstances = new Array(); var initializePatternInstances = true; // initialize patternInstances array the first time inspectionGetToolpathId is called function inspectionGetToolpathId(section) { if (initializePatternInstances) { for (var i = 0; i < getNumberOfSections(); ++i) { var _section = getSection(i); if (_section.getInternalPatternId) { var sectionId = _section.getId(); var patternId = _section.getInternalPatternId(); var isPatterned = _section.isPatterned && _section.isPatterned(); var isMirrored = patternId != _section.getPatternId(); if (isPatterned || isMirrored) { var isKnownPatternId = false; for (var j = 0; j < patternInstances.length; j++) { if (patternId == patternInstances[j].patternId) { patternInstances[j].patternIndex++; patternInstances[j].sections.push(sectionId); isKnownPatternId = true; break; } } if (!isKnownPatternId) { patternInstances.push({patternId:patternId, patternIndex:1, sections:[sectionId]}); } } } } initializePatternInstances = false; } var _operationId = section.getParameter("autodeskcam:operation-id", ""); var key = -1; for (k in patternInstances) { if (patternInstances[k].patternId == _operationId) { key = k; break; } } var _patternId = (key > -1) ? patternInstances[key].sections.indexOf(section.getId()) + 1 : 0; var _cycleId = cycle && ("cycleID" in cycle) ? cycle.cycleID : section.getParameter("cycleID", 0); if (isProbeOperation(section) && _cycleId == 0 && getGlobalParameter("product-id").toLowerCase().indexOf("fusion") > -1) { // we expect the cycleID to be non zero always for macro probing toolpaths, Fusion only warningOnce(localize("Outdated macro probing operations detected. Please regenerate all macro probing operations."), WARNING_OUTDATED); } if (_patternId > 99) { error(subst(localize("The maximum number of pattern instances is limited to 99" + EOL + "You need to split operation '%1' into separate pattern groups." ), section.getParameter("operation-comment", ""))); } if (_cycleId > 99) { error(subst(localize("The maximum number of probing cycles is limited to 99" + EOL + "You need to split operation '%1' to multiple operations with less than 100 cycles in each operation." ), section.getParameter("operation-comment", ""))); } return toolpathIdFormat.format(_operationId + (_cycleId * 0.01) + (_patternId * 0.0001) + 0.00001); } var localVariableStart = 19; var localVariable = [ macroFormat.format(localVariableStart + 1), macroFormat.format(localVariableStart + 2), macroFormat.format(localVariableStart + 3), macroFormat.format(localVariableStart + 4), macroFormat.format(localVariableStart + 5), macroFormat.format(localVariableStart + 6) ]; function defineLocalVariable(indx, value) { writeln(localVariable[indx - 1] + " = " + value); } function formatLocalVariable(prefix, indx, rnd) { return prefix + localVariable[indx - 1] + rnd; } function inspectionCreateResultsFileHeader() { if (isDPRNTopen) { if (!getProperty("singleResultsFile")) { writeln("DPRNT[END]"); writeBlock("PCLOS"); isDPRNTopen = false; } } if (isProbeOperation() && !printProbeResults()) { return; // if print results is not desired by probe/ probeWCS } if (!isDPRNTopen) { writeBlock("PCLOS"); writeBlock("POPEN"); // check for existence of none alphanumeric characters but not spaces var resFile; if (getProperty("singleResultsFile")) { resFile = getParameter("job-description") + "-RESULTS"; } else { resFile = getParameter("operation-comment") + "-RESULTS"; } resFile = resFile.replace(/:/g, "-"); resFile = resFile.replace(/[^a-zA-Z0-9 -]/g, ""); resFile = resFile.replace(/\s/g, "-"); resFile = resFile.toUpperCase(); writeln("DPRNT[START]"); writeln("DPRNT[RESULTSFILE*" + resFile + "]"); if (hasGlobalParameter("document-id")) { writeln("DPRNT[DOCUMENTID*" + getGlobalParameter("document-id").toUpperCase() + "]"); } if (hasGlobalParameter("model-version")) { writeln("DPRNT[MODELVERSION*" + getGlobalParameter("model-version").toUpperCase() + "]"); } } if (isProbeOperation() && printProbeResults()) { isDPRNTopen = true; } } function getPointNumber() { if (typeof inspectionWriteVariables == "function") { return (inspectionVariables.pointNumber); } else { return ("#122[60]"); } } function inspectionWriteCADTransform() { var cadOrigin = currentSection.getModelOrigin(); var cadWorkPlane = currentSection.getModelPlane().getTransposed(); var cadEuler = cadWorkPlane.getEuler2(EULER_XYZ_S); defineLocalVariable(1, abcFormat.format(cadEuler.x)); defineLocalVariable(2, abcFormat.format(cadEuler.y)); defineLocalVariable(3, abcFormat.format(cadEuler.z)); defineLocalVariable(4, xyzFormat.format(-cadOrigin.x)); defineLocalVariable(5, xyzFormat.format(-cadOrigin.y)); defineLocalVariable(6, xyzFormat.format(-cadOrigin.z)); writeln( "DPRNT[G331" + "*N" + getPointNumber() + formatLocalVariable("*A", 1, macroRoundingFormat) + formatLocalVariable("*B", 2, macroRoundingFormat) + formatLocalVariable("*C", 3, macroRoundingFormat) + formatLocalVariable("*X", 4, macroRoundingFormat) + formatLocalVariable("*Y", 5, macroRoundingFormat) + formatLocalVariable("*Z", 6, macroRoundingFormat) + "]" ); } function inspectionWriteWorkplaneTransform() { var orientation = machineConfiguration.isMultiAxisConfiguration() ? machineConfiguration.getOrientation(getCurrentDirection()) : currentSection.workPlane; var abc = orientation.getEuler2(EULER_XYZ_S); if (getProperty("useLiveConnection")) { liveConnectorInterface("WORKPLANE"); writeBlock(inspectionVariables.liveConnectionWPA, "=", abcFormat.format(abc.x)); writeBlock(inspectionVariables.liveConnectionWPB, "=", abcFormat.format(abc.y)); writeBlock(inspectionVariables.liveConnectionWPC, "=", abcFormat.format(abc.z)); forceSequenceNumbers(true); writeBlock("IF [" + inspectionVariables.workplaneStartAddress, "NE -1] GOTO" + skipNLines(2)); writeBlock(inspectionVariables.workplaneStartAddress, "=", inspectionGetToolpathId(currentSection)); writeBlock(" "); forceSequenceNumbers(false); } defineLocalVariable(1, abcFormat.format(abc.x)); defineLocalVariable(2, abcFormat.format(abc.y)); defineLocalVariable(3, abcFormat.format(abc.z)); writeln("DPRNT[G330" + "*N" + getPointNumber() + formatLocalVariable("*A", 1, macroRoundingFormat) + formatLocalVariable("*B", 2, macroRoundingFormat) + formatLocalVariable("*C", 3, macroRoundingFormat) + "*X0*Y0*Z0*I0*R0]" ); } function writeProbingToolpathInformation(cycleDepth) { defineLocalVariable(1, inspectionGetToolpathId(currentSection)); writeln(formatLocalVariable("DPRNT[TOOLPATHID*", 1, "[35]]")); if (isInspectionOperation()) { writeln("DPRNT[TOOLPATH*" + getParameter("operation-comment").toUpperCase().replace(/[()]/g, "") + "]"); } else { defineLocalVariable(2, xyzFormat.format(cycleDepth)); writeln(formatLocalVariable("DPRNT[CYCLEDEPTH*", 2, macroRoundingFormat + "]")); } } // <<<<< INCLUDED FROM include_files/commonInspectionFunctions_fanuc.cpi // >>>>> INCLUDED FROM include_files/probeCycles_renishaw.cpi validate(settings.probing, "Setting 'probing' is required but not defined."); var probeVariables = { outputRotationCodes: false, // determines if it is required to output rotation codes compensationXY : undefined, probeAngleMethod : undefined, rotaryTableAxis : -1 }; function writeProbeCycle(cycle, x, y, z, P, F) { if (isProbeOperation()) { if (!settings.workPlaneMethod.useTiltedWorkplane && !isSameDirection(currentSection.workPlane.forward, new Vector(0, 0, 1))) { if (!settings.probing.allowIndexingWCSProbing && currentSection.strategy == "probe") { error(localize("Updating WCS / work offset using probing is only supported by the CNC in the WCS frame.")); return; } } if (printProbeResults()) { writeProbingToolpathInformation(z - cycle.depth + tool.diameter / 2); inspectionWriteCADTransform(); inspectionWriteWorkplaneTransform(); if (typeof inspectionWriteVariables == "function") { inspectionVariables.pointNumber += 1; } } protectedProbeMove(cycle, x, y, z); } var macroCall = settings.probing.macroCall; switch (cycleType) { case "probing-x": protectedProbeMove(cycle, x, y, z - cycle.depth); writeBlock( macroCall, "P" + 9811, "X" + xyzFormat.format(x + approach(cycle.approach1) * (cycle.probeClearance + tool.diameter / 2)), "Q" + xyzFormat.format(cycle.probeOvertravel), getProbingArguments(cycle, true) ); break; case "probing-y": protectedProbeMove(cycle, x, y, z - cycle.depth); writeBlock( macroCall, "P" + 9811, "Y" + xyzFormat.format(y + approach(cycle.approach1) * (cycle.probeClearance + tool.diameter / 2)), "Q" + xyzFormat.format(cycle.probeOvertravel), getProbingArguments(cycle, true) ); break; case "probing-z": protectedProbeMove(cycle, x, y, Math.min(z - cycle.depth + cycle.probeClearance, cycle.retract)); writeBlock( macroCall, "P" + 9811, "Z" + xyzFormat.format(z - cycle.depth), "Q" + xyzFormat.format(cycle.probeOvertravel), getProbingArguments(cycle, true) ); break; case "probing-x-wall": protectedProbeMove(cycle, x, y, z); writeBlock( macroCall, "P" + 9812, "X" + xyzFormat.format(cycle.width1), zOutput.format(z - cycle.depth), "Q" + xyzFormat.format(cycle.probeOvertravel), "R" + xyzFormat.format(cycle.probeClearance), getProbingArguments(cycle, true) ); break; case "probing-y-wall": protectedProbeMove(cycle, x, y, z); writeBlock( macroCall, "P" + 9812, "Y" + xyzFormat.format(cycle.width1), zOutput.format(z - cycle.depth), "Q" + xyzFormat.format(cycle.probeOvertravel), "R" + xyzFormat.format(cycle.probeClearance), getProbingArguments(cycle, true) ); break; case "probing-x-channel": protectedProbeMove(cycle, x, y, z - cycle.depth); writeBlock( macroCall, "P" + 9812, "X" + xyzFormat.format(cycle.width1), "Q" + xyzFormat.format(cycle.probeOvertravel), // not required "R" + xyzFormat.format(cycle.probeClearance), getProbingArguments(cycle, true) ); break; case "probing-x-channel-with-island": protectedProbeMove(cycle, x, y, z); writeBlock( macroCall, "P" + 9812, "X" + xyzFormat.format(cycle.width1), zOutput.format(z - cycle.depth), "Q" + xyzFormat.format(cycle.probeOvertravel), "R" + xyzFormat.format(-cycle.probeClearance), getProbingArguments(cycle, true) ); break; case "probing-y-channel": protectedProbeMove(cycle, x, y, z - cycle.depth); writeBlock( macroCall, "P" + 9812, "Y" + xyzFormat.format(cycle.width1), "Q" + xyzFormat.format(cycle.probeOvertravel), // not required "R" + xyzFormat.format(cycle.probeClearance), getProbingArguments(cycle, true) ); break; case "probing-y-channel-with-island": protectedProbeMove(cycle, x, y, z); writeBlock( macroCall, "P" + 9812, "Y" + xyzFormat.format(cycle.width1), zOutput.format(z - cycle.depth), "Q" + xyzFormat.format(cycle.probeOvertravel), "R" + xyzFormat.format(-cycle.probeClearance), getProbingArguments(cycle, true) ); break; case "probing-xy-circular-boss": protectedProbeMove(cycle, x, y, z); writeBlock( macroCall, "P" + 9814, "D" + xyzFormat.format(cycle.width1), "Z" + xyzFormat.format(z - cycle.depth), "Q" + xyzFormat.format(cycle.probeOvertravel), "R" + xyzFormat.format(cycle.probeClearance), getProbingArguments(cycle, true) ); break; case "probing-xy-circular-partial-boss": protectedProbeMove(cycle, x, y, z); writeBlock( macroCall, "P" + 9823, "A" + xyzFormat.format(cycle.partialCircleAngleA), "B" + xyzFormat.format(cycle.partialCircleAngleB), "C" + xyzFormat.format(cycle.partialCircleAngleC), "D" + xyzFormat.format(cycle.width1), "Z" + xyzFormat.format(z - cycle.depth), "Q" + xyzFormat.format(cycle.probeOvertravel), "R" + xyzFormat.format(cycle.probeClearance), getProbingArguments(cycle, true) ); break; case "probing-xy-circular-hole": protectedProbeMove(cycle, x, y, z - cycle.depth); writeBlock( macroCall, "P" + 9814, "D" + xyzFormat.format(cycle.width1), "Q" + xyzFormat.format(cycle.probeOvertravel), // not required "R" + xyzFormat.format(cycle.probeClearance), getProbingArguments(cycle, true) ); break; case "probing-xy-circular-partial-hole": protectedProbeMove(cycle, x, y, z - cycle.depth); writeBlock( macroCall, "P" + 9823, "A" + xyzFormat.format(cycle.partialCircleAngleA), "B" + xyzFormat.format(cycle.partialCircleAngleB), "C" + xyzFormat.format(cycle.partialCircleAngleC), "D" + xyzFormat.format(cycle.width1), "Q" + xyzFormat.format(cycle.probeOvertravel), getProbingArguments(cycle, true) ); break; case "probing-xy-circular-hole-with-island": protectedProbeMove(cycle, x, y, z); writeBlock( macroCall, "P" + 9814, "Z" + xyzFormat.format(z - cycle.depth), "D" + xyzFormat.format(cycle.width1), "Q" + xyzFormat.format(cycle.probeOvertravel), "R" + xyzFormat.format(-cycle.probeClearance), getProbingArguments(cycle, true) ); break; case "probing-xy-circular-partial-hole-with-island": protectedProbeMove(cycle, x, y, z); writeBlock( macroCall, "P" + 9823, "Z" + xyzFormat.format(z - cycle.depth), "A" + xyzFormat.format(cycle.partialCircleAngleA), "B" + xyzFormat.format(cycle.partialCircleAngleB), "C" + xyzFormat.format(cycle.partialCircleAngleC), "D" + xyzFormat.format(cycle.width1), "Q" + xyzFormat.format(cycle.probeOvertravel), "R" + xyzFormat.format(-cycle.probeClearance), getProbingArguments(cycle, true) ); break; case "probing-xy-rectangular-hole": protectedProbeMove(cycle, x, y, z - cycle.depth); writeBlock( macroCall, "P" + 9812, "X" + xyzFormat.format(cycle.width1), "Q" + xyzFormat.format(cycle.probeOvertravel), // not required "R" + xyzFormat.format(-cycle.probeClearance), getProbingArguments(cycle, true) ); if (getProperty("useLiveConnection") && (typeof liveConnectionStoreResults == "function")) { liveConnectionStoreResults(); } writeBlock( macroCall, "P" + 9812, "Y" + xyzFormat.format(cycle.width2), "Q" + xyzFormat.format(cycle.probeOvertravel), // not required "R" + xyzFormat.format(-cycle.probeClearance), getProbingArguments(cycle, true) ); break; case "probing-xy-rectangular-boss": protectedProbeMove(cycle, x, y, z); writeBlock( macroCall, "P" + 9812, "Z" + xyzFormat.format(z - cycle.depth), "X" + xyzFormat.format(cycle.width1), "R" + xyzFormat.format(cycle.probeClearance), "Q" + xyzFormat.format(cycle.probeOvertravel), getProbingArguments(cycle, true) ); if (getProperty("useLiveConnection") && (typeof liveConnectionStoreResults == "function")) { liveConnectionStoreResults(); } writeBlock( macroCall, "P" + 9812, "Z" + xyzFormat.format(z - cycle.depth), "Y" + xyzFormat.format(cycle.width2), "R" + xyzFormat.format(cycle.probeClearance), "Q" + xyzFormat.format(cycle.probeOvertravel), getProbingArguments(cycle, true) ); break; case "probing-xy-rectangular-hole-with-island": protectedProbeMove(cycle, x, y, z); writeBlock( macroCall, "P" + 9812, "Z" + xyzFormat.format(z - cycle.depth), "X" + xyzFormat.format(cycle.width1), "Q" + xyzFormat.format(cycle.probeOvertravel), "R" + xyzFormat.format(-cycle.probeClearance), getProbingArguments(cycle, true) ); if (getProperty("useLiveConnection") && (typeof liveConnectionStoreResults == "function")) { liveConnectionStoreResults(); } writeBlock( macroCall, "P" + 9812, "Z" + xyzFormat.format(z - cycle.depth), "Y" + xyzFormat.format(cycle.width2), "Q" + xyzFormat.format(cycle.probeOvertravel), "R" + xyzFormat.format(-cycle.probeClearance), getProbingArguments(cycle, true) ); break; case "probing-xy-inner-corner": var cornerX = x + approach(cycle.approach1) * (cycle.probeClearance + tool.diameter / 2); var cornerY = y + approach(cycle.approach2) * (cycle.probeClearance + tool.diameter / 2); var cornerI = 0; var cornerJ = 0; if (cycle.probeSpacing !== undefined) { cornerI = cycle.probeSpacing; cornerJ = cycle.probeSpacing; } if ((cornerI != 0) && (cornerJ != 0)) { if (currentSection.strategy == "probe") { setProbeAngleMethod(); } } protectedProbeMove(cycle, x, y, z - cycle.depth); writeBlock( macroCall, "P" + 9815, xOutput.format(cornerX), yOutput.format(cornerY), conditional(cornerI != 0, "I" + xyzFormat.format(cornerI)), conditional(cornerJ != 0, "J" + xyzFormat.format(cornerJ)), "Q" + xyzFormat.format(cycle.probeOvertravel), getProbingArguments(cycle, true) ); break; case "probing-xy-outer-corner": var cornerX = x + approach(cycle.approach1) * (cycle.probeClearance + tool.diameter / 2); var cornerY = y + approach(cycle.approach2) * (cycle.probeClearance + tool.diameter / 2); var cornerI = 0; var cornerJ = 0; if (cycle.probeSpacing !== undefined) { cornerI = cycle.probeSpacing; cornerJ = cycle.probeSpacing; } if ((cornerI != 0) && (cornerJ != 0)) { if (currentSection.strategy == "probe") { setProbeAngleMethod(); } } protectedProbeMove(cycle, x, y, z - cycle.depth); writeBlock( macroCall, "P" + 9816, xOutput.format(cornerX), yOutput.format(cornerY), conditional(cornerI != 0, "I" + xyzFormat.format(cornerI)), conditional(cornerJ != 0, "J" + xyzFormat.format(cornerJ)), "Q" + xyzFormat.format(cycle.probeOvertravel), getProbingArguments(cycle, true) ); break; case "probing-x-plane-angle": protectedProbeMove(cycle, x, y, z - cycle.depth); writeBlock( macroCall, "P" + 9843, "X" + xyzFormat.format(x + approach(cycle.approach1) * (cycle.probeClearance + tool.diameter / 2)), "D" + xyzFormat.format(cycle.probeSpacing), "Q" + xyzFormat.format(cycle.probeOvertravel), "A" + xyzFormat.format(cycle.nominalAngle != undefined ? cycle.nominalAngle : 90), getProbingArguments(cycle, false) ); if (currentSection.strategy == "probe") { setProbeAngleMethod(); probeVariables.compensationXY = "X" + xyzFormat.format(0) + " Y" + xyzFormat.format(0); } break; case "probing-y-plane-angle": protectedProbeMove(cycle, x, y, z - cycle.depth); writeBlock( macroCall, "P" + 9843, "Y" + xyzFormat.format(y + approach(cycle.approach1) * (cycle.probeClearance + tool.diameter / 2)), "D" + xyzFormat.format(cycle.probeSpacing), "Q" + xyzFormat.format(cycle.probeOvertravel), "A" + xyzFormat.format(cycle.nominalAngle != undefined ? cycle.nominalAngle : 0), getProbingArguments(cycle, false) ); if (currentSection.strategy == "probe") { setProbeAngleMethod(); probeVariables.compensationXY = "X" + xyzFormat.format(0) + " Y" + xyzFormat.format(0); } break; case "probing-xy-pcd-hole": protectedProbeMove(cycle, x, y, z); writeBlock( macroCall, "P" + 9819, "A" + xyzFormat.format(cycle.pcdStartingAngle), "B" + xyzFormat.format(cycle.numberOfSubfeatures), "C" + xyzFormat.format(cycle.widthPCD), "D" + xyzFormat.format(cycle.widthFeature), "K" + xyzFormat.format(z - cycle.depth), "Q" + xyzFormat.format(cycle.probeOvertravel), getProbingArguments(cycle, false) ); if (cycle.updateToolWear) { error(localize("Action -Update Tool Wear- is not supported with this cycle.")); return; } break; case "probing-xy-pcd-boss": protectedProbeMove(cycle, x, y, z); writeBlock( macroCall, "P" + 9819, "A" + xyzFormat.format(cycle.pcdStartingAngle), "B" + xyzFormat.format(cycle.numberOfSubfeatures), "C" + xyzFormat.format(cycle.widthPCD), "D" + xyzFormat.format(cycle.widthFeature), "Z" + xyzFormat.format(z - cycle.depth), "Q" + xyzFormat.format(cycle.probeOvertravel), "R" + xyzFormat.format(cycle.probeClearance), getProbingArguments(cycle, false) ); if (cycle.updateToolWear) { error(localize("Action -Update Tool Wear- is not supported with this cycle.")); return; } break; } } function printProbeResults() { return currentSection.getParameter("printResults", 0) == 1; } /** Convert approach to sign. */ function approach(value) { validate((value == "positive") || (value == "negative"), "Invalid approach."); return (value == "positive") ? 1 : -1; } // <<<<< INCLUDED FROM include_files/probeCycles_renishaw.cpi // >>>>> INCLUDED FROM include_files/getProbingArguments_renishaw.cpi function getProbingArguments(cycle, updateWCS) { var outputWCSCode = updateWCS && currentSection.strategy == "probe"; if (outputWCSCode) { var maximumWcsNumber = 0; for (var i in wcsDefinitions.wcs) { maximumWcsNumber = Math.max(maximumWcsNumber, wcsDefinitions.wcs[i].range[1]); } maximumWcsNumber = probeExtWCSFormat.getResultingValue(maximumWcsNumber); var resultingWcsNumber = probeExtWCSFormat.getResultingValue(currentSection.probeWorkOffset - 6); validate(resultingWcsNumber <= maximumWcsNumber, subst("Probe work offset %1 is out of range, maximum value is %2.", resultingWcsNumber, maximumWcsNumber)); var probeOutputWorkOffset = currentSection.probeWorkOffset > 6 ? probeExtWCSFormat.format(currentSection.probeWorkOffset - 6) : probeWCSFormat.format(currentSection.probeWorkOffset); var nextWorkOffset = hasNextSection() ? getNextSection().workOffset == 0 ? 1 : getNextSection().workOffset : -1; if (currentSection.probeWorkOffset == nextWorkOffset) { currentWorkOffset = undefined; } } return [ (cycle.angleAskewAction == "stop-message" ? "B" + xyzFormat.format(cycle.toleranceAngle ? cycle.toleranceAngle : 0) : undefined), ((cycle.updateToolWear && cycle.toolWearErrorCorrection < 100) ? "F" + xyzFormat.format(cycle.toolWearErrorCorrection ? cycle.toolWearErrorCorrection / 100 : 100) : undefined), (cycle.wrongSizeAction == "stop-message" ? "H" + xyzFormat.format(cycle.toleranceSize ? cycle.toleranceSize : 0) : undefined), (cycle.outOfPositionAction == "stop-message" ? "M" + xyzFormat.format(cycle.tolerancePosition ? cycle.tolerancePosition : 0) : undefined), ((cycle.updateToolWear && cycleType == "probing-z") ? "T" + xyzFormat.format(cycle.toolLengthOffset) : undefined), ((cycle.updateToolWear && cycleType !== "probing-z") ? "T" + xyzFormat.format(cycle.toolDiameterOffset) : undefined), (cycle.updateToolWear ? "V" + xyzFormat.format(cycle.toolWearUpdateThreshold ? cycle.toolWearUpdateThreshold : 0) : undefined), (cycle.printResults ? "W" + xyzFormat.format(1 + cycle.incrementComponent) : undefined), // 1 for advance feature, 2 for reset feature count and advance component number. first reported result in a program should use W2. conditional(outputWCSCode, probeOutputWorkOffset) ]; } // <<<<< INCLUDED FROM include_files/getProbingArguments_renishaw.cpi // >>>>> INCLUDED FROM include_files/protectedProbeMove_renishaw.cpi function protectedProbeMove(_cycle, x, y, z) { var _x = xOutput.format(x); var _y = yOutput.format(y); var _z = zOutput.format(z); var macroCall = settings.probing.macroCall; if (_z && z >= getCurrentPosition().z) { writeBlock(macroCall, "P" + 9810, _z, getFeed(cycle.feedrate)); // protected positioning move } if (_x || _y) { writeBlock(macroCall, "P" + 9810, _x, _y, getFeed(highFeedrate)); // protected positioning move } if (_z && z < getCurrentPosition().z) { writeBlock(macroCall, "P" + 9810, _z, getFeed(cycle.feedrate)); // protected positioning move } } // <<<<< INCLUDED FROM include_files/protectedProbeMove_renishaw.cpi // >>>>> INCLUDED FROM include_files/setProbeAngle_fanuc.cpi function setProbeAngle() { if (probeVariables.outputRotationCodes) { validate(settings.probing.probeAngleVariables, localize("Setting 'probing.probeAngleVariables' is required for angular probing.")); var probeAngleVariables = settings.probing.probeAngleVariables; var px = probeAngleVariables.x; var py = probeAngleVariables.y; var pz = probeAngleVariables.z; var pi = probeAngleVariables.i; var pj = probeAngleVariables.j; var pk = probeAngleVariables.k; var pr = probeAngleVariables.r; var baseParamG54x4 = probeAngleVariables.baseParamG54x4; var baseParamAxisRot = probeAngleVariables.baseParamAxisRot; var probeOutputWorkOffset = currentSection.probeWorkOffset; validate(probeOutputWorkOffset <= 6, "Angular Probing only supports work offsets 1-6."); if (probeVariables.probeAngleMethod == "G68" && (Vector.diff(currentSection.getGlobalInitialToolAxis(), new Vector(0, 0, 1)).length > 1e-4)) { error(localize("You cannot use multi axis toolpaths while G68 Rotation is in effect.")); } var validateWorkOffset = false; switch (probeVariables.probeAngleMethod) { case "G54.4": var param = baseParamG54x4 + (probeOutputWorkOffset * 10); writeBlock("#" + param + "=" + px); writeBlock("#" + (param + 1) + "=" + py); writeBlock("#" + (param + 5) + "=" + pr); writeBlock(gFormat.format(54.4), "P" + probeOutputWorkOffset); break; case "G68": gRotationModal.reset(); gAbsIncModal.reset(); var xy = probeVariables.compensationXY || formatWords(formatCompensationParameter("X", px), formatCompensationParameter("Y", py)); writeBlock( gRotationModal.format(68), gAbsIncModal.format(90), xy, formatCompensationParameter("Z", pz), formatCompensationParameter("I", pi), formatCompensationParameter("J", pj), formatCompensationParameter("K", pk), formatCompensationParameter("R", pr) ); validateWorkOffset = true; break; case "AXIS_ROT": var param = baseParamAxisRot + probeOutputWorkOffset * 20 + probeVariables.rotaryTableAxis + 4; writeBlock("#" + param + " = " + "[#" + param + " + " + pr + "]"); forceWorkPlane(); // force workplane to rotate ABC in order to apply rotation offsets currentWorkOffset = undefined; // force WCS output to make use of updated parameters validateWorkOffset = true; break; default: error(localize("Angular Probing is not supported for this machine configuration.")); return; } if (validateWorkOffset) { for (var i = currentSection.getId(); i < getNumberOfSections(); ++i) { if (getSection(i).workOffset != currentSection.workOffset) { error(localize("WCS offset cannot change while using angle rotation compensation.")); return; } } } probeVariables.outputRotationCodes = false; } } function formatCompensationParameter(label, value) { return typeof value == "string" ? label + "[" + value + "]" : typeof value == "number" ? label + xyzFormat.format(value) : ""; } // <<<<< INCLUDED FROM include_files/setProbeAngle_fanuc.cpi // >>>>> INCLUDED FROM include_files/setProbeAngleMethod.cpi function setProbeAngleMethod() { var axisRotIsSupported = false; var axes = [machineConfiguration.getAxisU(), machineConfiguration.getAxisV(), machineConfiguration.getAxisW()]; for (var i = 0; i < axes.length; ++i) { if (axes[i].isEnabled() && isSameDirection((axes[i].getAxis()).getAbsolute(), new Vector(0, 0, 1)) && axes[i].isTable()) { axisRotIsSupported = true; if (settings.probing.probeAngleVariables.method == 0) { // Fanuc validate(i < 2, localize("Rotary table axis is invalid.")); probeVariables.rotaryTableAxis = i; } else { // Haas probeVariables.rotaryTableAxis = axes[i].getCoordinate(); } break; } } if (settings.probing.probeAngleMethod == undefined) { probeVariables.probeAngleMethod = axisRotIsSupported ? "AXIS_ROT" : getProperty("useG54x4") ? "G54.4" : "G68"; // automatic selection } else { probeVariables.probeAngleMethod = settings.probing.probeAngleMethod; // use probeAngleMethod from settings if (probeVariables.probeAngleMethod == "AXIS_ROT" && !axisRotIsSupported) { error(localize("Setting probeAngleMethod 'AXIS_ROT' is not supported on this machine.")); } } probeVariables.outputRotationCodes = true; } // <<<<< INCLUDED FROM include_files/setProbeAngleMethod.cpi