From 57b5521968735ce7d32fda2a7350d944929d6317 Mon Sep 17 00:00:00 2001 From: will1742 Date: Mon, 14 Jun 2021 16:23:40 -0400 Subject: [PATCH 1/7] Basic M109 Functionality --- Haas_Next_Generation/haas vf2.cps | 4891 +++++++++++++++++++++++++++++ 1 file changed, 4891 insertions(+) create mode 100644 Haas_Next_Generation/haas vf2.cps diff --git a/Haas_Next_Generation/haas vf2.cps b/Haas_Next_Generation/haas vf2.cps new file mode 100644 index 0000000..c910818 --- /dev/null +++ b/Haas_Next_Generation/haas vf2.cps @@ -0,0 +1,4891 @@ +/** + Copyright (C) 2012-2021 by Autodesk, Inc. + All rights reserved. + + HAAS post processor configuration. + + $Revision: 43303 89bc27ff4d3595014e0e8cba412811fbed9f3e74 $ + $Date: 2021-06-01 08:35:38 $ + + FORKID {DBD402DA-DE90-4634-A6A3-0AE5CC97DEC7} +*/ + +// >>>>> INCLUDED FROM ../../../haas next generation.cps +//////////////////////////////////////////////////////////////////////////////////////////////// +// MANUAL NC COMMANDS +// +// The following ACTION commands are supported by this post. +// +// CYCLE_REVERSAL - Reverses the spindle in a drilling cycle +// USEPOLARMODE - Enables polar interpolation for the following operation. +// VFD_HIGH - Uses high pressure flood coolant if machine has VFD +// VFD_LOW - Uses low pressure flood coolant if machine has VFD +// VFD_NORMAL - Uses normal pressure flood coolant if machine has VFD +// +//////////////////////////////////////////////////////////////////////////////////////////////// + +description = "HAAS - Next Generation Control"; +vendor = "Haas Automation"; +vendorUrl = "https://www.haascnc.com"; +legal = "Copyright (C) 2012-2021 by Autodesk, Inc."; +certificationLevel = 2; +minimumRevision = 45702; + +longDescription = "Generic post for the HAAS Next Generation control. The post includes support for multi-axis indexing and simultaneous machining. The post utilizes the dynamic work offset feature so you can place your work piece as desired without having to repost your NC programs." + EOL + +"You can specify following pre-configured machines by using the property 'Machine model':" + EOL + +"UMC-500" + EOL + "UMC-750" + EOL + "UMC-1000" + EOL + "UMC-1600-H"; + +extension = "nc"; +programNameIsInteger = true; +setCodePage("ascii"); +keywords = "MODEL_IMAGE PREVIEW_IMAGE"; + +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(355); +allowHelicalMoves = true; +allowedCircularPlanes = undefined; // allow any circular motion +allowSpiralMoves = true; +highFeedrate = 650 * 25.4; // must be in MM + +// user-defined properties +properties = { + machineModel: { + title: "Machine model", + description: "Specifies the pre-configured machine model.", + type: "enum", + group: 0, + values: [ + {title: "None", id: "none"}, + {title: "UMC-500", id: "umc-500"}, + {title: "UMC-750", id: "umc-750"}, + {title: "UMC-1000", id: "umc-1000"}, + {title: "UMC-1600-H", id: "umc-1600"} + ], + value: "none", + scope: "post" + }, + hasAAxis: { + title: "Has A-axis rotary", + description: "Enable if the machine has an A-axis table/trunnion. Check the table direction on the machine and use the (Reversed) selection if the table is moving in the opposite direction.", + type: "enum", + group: 1, + values: [ + {title: "No", id: "false"}, + {title: "Yes", id: "true"}, + {title: "Reversed", id: "reversed"} + ], + value: "false", + scope: "post" + }, + hasBAxis: { + title: "Has B-axis rotary", + description: "Enable if the machine has a B-axis table/trunnion. Check the table direction on the machine and use the (Reversed) selection if the table is moving in the opposite direction.", + type: "enum", + group: 1, + values: [ + {title: "No", id: "false"}, + {title: "Yes", id: "true"}, + {title: "Reversed", id: "reversed"} + ], + value: "false", + scope: "post" + }, + hasCAxis: { + title: "Has C-axis rotary", + description: "Enable if the machine has a C-axis table. Specifies a trunnion setup if an A-axis or B-axis is defined. Check the table direction on the machine and use the (Reversed) selection if the table is moving in the opposite direction.", + type: "enum", + group: 1, + values: [ + {title: "No", id: "false"}, + {title: "Yes", id: "true"}, + {title: "Reversed", id: "reversed"} + ], + value: "false", + scope: "post" + }, + useDPMFeeds: { + title: "Rotary moves use DPM feeds", + description: "Enable to output DPM feeds, disable for Inverse Time feeds with rotary axes moves.", + group: 1, + type: "boolean", + value: false, + scope: "post" + }, + useTCPC: { + title: "Use TCPC programming", + description: "The control supports Tool Center Point Control programming.", + group: 1, + type: "boolean", + value: true, + scope: "post" + }, + useDWO: { + title: "Use DWO", + description: "Specifies that the Dynamic Work Offset feature (G254/G255) should be used.", + group: 1, + type: "boolean", + value: true, + scope: "post" + }, + preloadTool: { + title: "Preload tool", + description: "Preloads the next tool at a tool change (if any).", + group: 2, + type: "boolean", + value: true, + scope: "post" + }, + chipTransport: { + title: "Use chip transport", + description: "Enable to turn on chip transport at start of program.", + group: 2, + type: "boolean", + value: false, + scope: "post" + }, + optionalStop: { + title: "Optional stop", + description: "Specifies that optional stops M1 should be output at tool changes.", + group: 2, + type: "boolean", + value: true, + scope: "post" + }, + separateWordsWithSpace: { + title: "Separate words with space", + description: "Adds spaces between words if 'yes' is selected.", + group: 2, + type: "boolean", + value: true, + scope: "post" + }, + useRadius: { + title: "Radius arcs", + description: "If yes is selected, arcs are output using radius values rather than IJK.", + group: 2, + type: "boolean", + value: false, + scope: "post" + }, + useParametricFeed: { + title: "Parametric feed", + description: "Parametric feed values based on movement type are output.", + group: 2, + type: "boolean", + value: false, + scope: "post" + }, + useG0: { + title: "Use G0", + description: "Specifies that G0s should be used for rapid moves when moving along a single axis.", + group: 2, + type: "boolean", + value: false, + scope: "post" + }, + safePositionMethod: { + title: "Safe Retracts", + description: "Select your desired retract option. 'Clearance Height' retracts to the operation clearance height.", + type: "enum", + values: [ + {title: "G28", id: "G28"}, + {title: "G53", id: "G53"}, + {title: "Clearance Height", id: "clearanceHeight"} + ], + value: "G53", + scope: "post" + }, + useG187: { + title: "Use G187", + description: "Specifies that smoothing using G187 should be used.", + group: 2, + type: "boolean", + value: false, + scope: "post" + }, + homePositionCenter: { + title: "Home position center", + description: "Enable to center the part along X at the end of program for easy access. Requires a CNC with a moving table.", + group: 2, + type: "boolean", + value: false, + scope: "post" + }, + optionallyCycleToolsAtStart: { + title: "Optionally cycle tools at start", + description: "Cycle through each tool used at the beginning of the program when block delete is turned off.", + group: 2, + type: "boolean", + value: false, + scope: "post" + }, + optionallyMeasureToolsAtStart: { + title: "Optionally measure tools at start", + description: "Measure each tool used at the beginning of the program when block delete is turned off.", + group: 2, + type: "boolean", + value: false, + scope: "post" + }, + forceHomeOnIndexing: { + title: "Force XY home position on indexing", + description: "Move XY to their home positions on multi-axis indexing.", + group: 2, + type: "boolean", + value: true, + scope: "post" + }, + toolBreakageTolerance: { + title: "Tool breakage tolerance", + description: "Specifies the tolerance for which tool break detection will raise an alarm.", + group: 2, + type: "spatial", + value: 0.1, + scope: "post" + }, + safeStartAllOperations: { + title: "Safe start all operations", + description: "Write optional blocks at the beginning of all operations that include all commands to start program.", + group: 2, + type: "boolean", + value: false, + scope: "post" + }, + fastToolChange: { + title: "Fast tool change", + description: "Skip spindle off, coolant off, and Z retract to make tool change quicker.", + group: 2, + type: "boolean", + value: false, + scope: "post" + }, + useG95forTapping: { + title: "Use G95 for tapping", + description: "use IPR/MPR instead of IPM/MPM for tapping", + group: 2, + type: "boolean", + value: false, + scope: "post" + }, + safeRetractDistance: { + title: "Safe retract distance", + description: "Specifies the distance to add to retract distance when rewinding rotary axes.", + group: 2, + type: "spatial", + value: 0, + scope: "post" + }, + useSubroutines: { + title: "Use subroutines", + description: "Select your desired subroutine option. 'All Operations' creates subroutines per each operation, 'Cycles' creates subroutines for cycle operations on same holes, and 'Patterns' creates subroutines for patterned operations.", + type: "enum", + values: [ + {title: "No", id: "none"}, + {title: "All Operations", id: "allOperations"}, + {title: "Cycles", id: "cycles"}, + {title: "Patterns", id: "patterns"} + ], + group: 3, + value: "none", + scope: "post" + }, + writeMachine: { + title: "Write machine", + description: "Output the machine settings in the header of the code.", + group: 4, + type: "boolean", + value: false, + scope: "post" + }, + writeTools: { + title: "Write tool list", + description: "Output a tool list in the header of the code.", + group: 4, + type: "boolean", + value: true, + scope: "post" + }, + writeVersion: { + title: "Write version", + description: "Write the version number in the header of the code.", + group: 4, + type: "boolean", + value: false, + scope: "post" + }, + showSequenceNumbers: { + title: "Use sequence numbers", + description: "Use sequence numbers for each block of outputted code.", + group: 4, + type: "boolean", + value: true, + scope: "post" + }, + sequenceNumberStart: { + title: "Start sequence number", + description: "The number at which to start the sequence numbers.", + group: 4, + type: "integer", + value: 10, + scope: "post" + }, + sequenceNumberIncrement: { + title: "Sequence number increment", + description: "The amount by which the sequence number is incremented by in each block.", + group: 4, + type: "integer", + value: 5, + scope: "post" + }, + sequenceNumberOnlyOnToolChange: { + title: "Block number only on tool change", + description: "Specifies that block numbers should only be output at tool changes.", + group: 4, + type: "boolean", + value: false, + scope: "post" + }, + showNotes: { + title: "Show notes", + description: "Enable to output notes for operations.", + group: 4, + type: "boolean", + value: false, + scope: "post" + }, + useM130PartImages: { + title: "Include M130 part images", + description: "Enable to include M130 part images with the NC file.", + group: 4, + type: "boolean", + value: false, + scope: "post" + }, + useM130ToolImages: { + title: "Include M130 tool images", + description: "Enable to include M130 tool images with the NC file.", + group: 4, + type: "boolean", + value: false, + scope: "post" + }, + coolantPressure: { + title: "Coolant pressure", + description: "Select the coolant pressure if equipped with a Variable Frequency Drive. Select 'Default' if this option is not installed.", + type: "enum", + group: 2, + values: [ + {title: "Default", id: ""}, + {title: "Low", id: "P0"}, + {title: "Normal", id: "P1"}, + {title: "High", id: "P2"} + ], + value: "", + 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: 0, + type: "boolean", + value: true, + scope: "post" + } +}; + +var singleLineCoolant = false; // specifies to output multiple coolant codes in one line rather than in separate lines +// samples: +// {id: COOLANT_THROUGH_TOOL, on: 88, off: 89} +// {id: COOLANT_THROUGH_TOOL, on: [8, 88], off: [9, 89]} +var coolants = [ + {id: COOLANT_FLOOD, on: 8}, + {id: COOLANT_MIST}, + {id: COOLANT_THROUGH_TOOL, on: 88, off: 89}, + {id: COOLANT_AIR, on: 83, off: 84}, + {id: COOLANT_AIR_THROUGH_TOOL, on: 73, off: 74}, + {id: COOLANT_SUCTION}, + {id: COOLANT_FLOOD_MIST}, + {id: COOLANT_FLOOD_THROUGH_TOOL, on: [88, 8], off: [89, 9]}, + {id: COOLANT_OFF, off: 9} +]; + +// old machines only support 4 digits +var oFormat = createFormat({width:5, zeropad:true, decimals:0}); +var nFormat = createFormat({decimals:0}); + +var gFormat = createFormat({prefix:"G", decimals:0}); +var mFormat = createFormat({prefix:"M", decimals:0}); +var hFormat = createFormat({prefix:"H", decimals:0}); +var dFormat = createFormat({prefix:"D", decimals:0}); +var probeWCSFormat = createFormat({decimals:2, forceDecimal:true}); + +var xyzFormat = createFormat({decimals:(unit == MM ? 3 : 4), forceDecimal:true}); +var rFormat = xyzFormat; // radius +var abcFormat = createFormat({decimals:3, forceDecimal:true, scale:DEG}); +var feedFormat = createFormat({decimals:(unit == MM ? 2 : 3), forceDecimal:true}); +var pitchFormat = createFormat({decimals:(unit == MM ? 3 : 4), forceDecimal:true}); +var toolFormat = createFormat({decimals:0}); +var rpmFormat = createFormat({decimals:0}); +var secFormat = createFormat({decimals:3, forceDecimal:true}); // seconds - range 0.001-1000 +var milliFormat = createFormat({decimals:0}); // milliseconds // range 1-9999 +var taperFormat = createFormat({decimals:1, scale:DEG}); + +var xOutput = createVariable({prefix:"X"}, xyzFormat); +var yOutput = createVariable({prefix:"Y"}, xyzFormat); +var zOutput = createVariable({onchange: function() {retracted = false;}, prefix:"Z"}, xyzFormat); +var aOutput = createVariable({prefix:"A"}, abcFormat); +var bOutput = createVariable({prefix:"B"}, abcFormat); +var cOutput = createVariable({prefix:"C"}, abcFormat); +var feedOutput = createVariable({prefix:"F"}, feedFormat); +var pitchOutput = createVariable({prefix:"F", force:true}, pitchFormat); +var sOutput = createVariable({prefix:"S", force:true}, rpmFormat); +var dOutput = createVariable({}, dFormat); + +// circular output +var iOutput = createReferenceVariable({prefix:"I", force:true}, xyzFormat); +var jOutput = createReferenceVariable({prefix:"J", force:true}, xyzFormat); +var kOutput = createReferenceVariable({prefix:"K", force:true}, xyzFormat); + +var gMotionModal = createModal({}, gFormat); // modal group 1 // G0-G3, ... +var gPlaneModal = createModal({onchange:function () {gMotionModal.reset();}}, gFormat); // modal group 2 // G17-19 +var gAbsIncModal = createModal({}, gFormat); // modal group 3 // G90-91 +var gFeedModeModal = createModal({}, gFormat); // modal group 5 // G93-94 +var gUnitModal = createModal({}, gFormat); // modal group 6 // G20-21 +var gCycleModal = createModal({}, gFormat); // modal group 9 // G81, ... +var gRetractModal = createModal({force:true}, gFormat); // modal group 10 // G98-99 +var gRotationModal = createModal({ + onchange: function () { + if (probeVariables.probeAngleMethod == "G68") { + probeVariables.outputRotationCodes = true; + } + } +}, gFormat); // modal group 16 // G68-G69 + +// fixed settings +var firstFeedParameter = 100; // the first variable to use with parametric feed +var forceResetWorkPlane = false; // enable to force reset of machine ABC on new orientation +var minimumCyclePoints = 5; // minimum number of points in cycle operation to consider for subprogram +var useDwoForPositioning = true; // specifies to use the DWO feature for XY positioning for multi-axis operations + +var WARNING_WORK_OFFSET = 0; + +var allowIndexingWCSProbing = false; // specifies that probe WCS with tool orientation is supported +var probeVariables = { + outputRotationCodes: false, // defines if it is required to output rotation codes + probeAngleMethod: "OFF", // OFF, AXIS_ROT, G68, G54.4 + compensationXY: undefined, + rotationalAxis: -1 +}; + +var SUB_UNKNOWN = 0; +var SUB_PATTERN = 1; +var SUB_CYCLE = 2; + +// collected state +var sequenceNumber; +var currentWorkOffset; +var coolantPressure; +var optionalSection = false; +var forceSpindleSpeed = false; +var forceCoolant = false; +var activeMovements; // do not use by default +var currentFeedId; +var maximumCircularRadiiDifference = toPreciseUnit(0.005, MM); +var maximumLineLength = 80; // the maximum number of charaters allowed in a line +var subprograms = []; +var currentPattern = -1; +var firstPattern = false; +var currentSubprogram; +var lastSubprogram; +var initialSubprogramNumber = 90000; +var definedPatterns = new Array(); +var incrementalMode = false; +var saveShowSequenceNumbers; +var cycleSubprogramIsActive = false; +var patternIsActive = false; +var lastOperationComment = ""; +var incrementalSubprogram; +var retracted = false; // specifies that the tool has been retracted to the safe plane +var hasA = false; +var hasB = false; +var hasC = false; +var measureTool = false; +var cycleReverse = false; +probeMultipleFeatures = true; +var maximumSpindleRPM = 15000; +var homePositionCenter = false; + +// used to convert blocks to optional for safeStartAllOperations, might get used outside of onSection +var operationNeedsSafeStart = false; + +/** + Writes the specified block. +*/ +var skipBlock = false; +function writeBlock() { + var text = formatWords(arguments); + if (!text) { + return; + } + var maximumSequenceNumber = ((getProperty("useSubroutines") == "allOperations") || (getProperty("useSubroutines") == "patterns") || + (getProperty("useSubroutines") == "cycles")) ? initialSubprogramNumber : 99999; + if (getProperty("showSequenceNumbers")) { + if (sequenceNumber >= maximumSequenceNumber) { + sequenceNumber = getProperty("sequenceNumberStart"); + } + if (optionalSection || skipBlock) { + if (text) { + writeWords("/", "N" + sequenceNumber, text); + } + } else { + writeWords2("N" + sequenceNumber, arguments); + } + sequenceNumber += getProperty("sequenceNumberIncrement"); + } else { + if (optionalSection || skipBlock) { + writeWords2("/", arguments); + } else { + writeWords(arguments); + } + } + skipBlock = false; +} + +/** + Writes the specified block - used for tool changes only. +*/ +function writeToolBlock() { + var show = getProperty("showSequenceNumbers"); + setProperty("showSequenceNumbers", show || getProperty("sequenceNumberOnlyOnToolChange")); + writeBlock(arguments); + setProperty("showSequenceNumbers", show); +} + +/** + Writes the specified optional block. +*/ +function writeOptionalBlock() { + skipBlock = true; + writeBlock(arguments); +} + +function formatComment(text) { + return "(" + String(text).replace(/[()]/g, "") + ")"; +} + +/** + Output a comment. +*/ +function writeComment(text) { + writeln(formatComment(text.substr(0, maximumLineLength - 2))); +} + +/** + Returns the matching HAAS tool type for the tool. +*/ +function getHaasToolType(toolType) { + switch (toolType) { + case TOOL_DRILL: + case TOOL_REAMER: + return 1; // drill + case TOOL_TAP_RIGHT_HAND: + case TOOL_TAP_LEFT_HAND: + return 2; // tap + case TOOL_MILLING_FACE: + case TOOL_MILLING_SLOT: + case TOOL_BORING_BAR: + return 3; // shell mill + case TOOL_MILLING_END_FLAT: + case TOOL_MILLING_END_BULLNOSE: + case TOOL_MILLING_TAPERED: + case TOOL_MILLING_DOVETAIL: + return 4; // end mill + case TOOL_DRILL_SPOT: + case TOOL_MILLING_CHAMFER: + case TOOL_DRILL_CENTER: + case TOOL_COUNTER_SINK: + case TOOL_COUNTER_BORE: + case TOOL_MILLING_THREAD: + case TOOL_MILLING_FORM: + return 5; // center drill + case TOOL_MILLING_END_BALL: + case TOOL_MILLING_LOLLIPOP: + return 6; // ball nose + case TOOL_PROBE: + return 7; // probe + default: + error(localize("Invalid HAAS tool type.")); + return -1; + } +} + +function getHaasProbingType(toolType, use9023) { + switch (getHaasToolType(toolType)) { + case 3: + case 4: + return (use9023 ? 23 : 1); // rotate + case 1: + case 2: + case 5: + case 6: + case 7: + return (use9023 ? 12 : 2); // non rotate + case 0: + return (use9023 ? 13 : 3); // rotate length and dia + default: + error(localize("Invalid HAAS tool type.")); + return -1; + } +} + +function writeToolCycleBlock(tool) { + writeOptionalBlock("T" + toolFormat.format(tool.number), mFormat.format(6)); // get tool + writeOptionalBlock(mFormat.format(0)); // wait for operator +} + +function prepareForToolCheck() { + onCommand(COMMAND_STOP_SPINDLE); + onCommand(COMMAND_COOLANT_OFF); + + // cancel TCP so that tool doesn't follow tables + if (currentSection.isMultiAxis() && tcpIsSupported) { + disableLengthCompensation(false, "TCPC OFF"); + } + if ((currentSection.isMultiAxis() && getCurrentDirection().length != 0) || + (currentMachineABC != undefined && currentMachineABC.length != 0)) { + setWorkPlane(new Vector(0, 0, 0)); + forceWorkPlane(); + } +} + +function writeToolMeasureBlock(tool, preMeasure) { + var writeFunction = measureTool ? writeBlock : writeOptionalBlock; + var comment = measureTool ? formatComment("MEASURE TOOL") : ""; + + if (!preMeasure) { + prepareForToolCheck(); + } + if (true) { // use Macro P9023 to measure tools + var probingType = getHaasProbingType(tool.type, true); + writeFunction( + gFormat.format(65), + "P9023", + "A" + probingType + ".", + "T" + toolFormat.format(tool.number), + conditional((probingType != 12), "H" + xyzFormat.format(tool.bodyLength + tool.holderLength)), + conditional((probingType != 12), "D" + xyzFormat.format(tool.diameter)), + comment + ); + } else { // use Macro P9995 to measure tools + writeFunction("T" + toolFormat.format(tool.number), mFormat.format(6)); // get tool + writeFunction( + gFormat.format(65), + "P9995", + "A0.", + "B" + getHaasToolType(tool.type) + ".", + "C" + getHaasProbingType(tool.type, false) + ".", + "T" + toolFormat.format(tool.number), + "E" + xyzFormat.format(tool.bodyLength + tool.holderLength), + "D" + xyzFormat.format(tool.diameter), + "K" + xyzFormat.format(0.1), + "I0.", + comment + ); // probe tool + } + measureTool = false; +} + +function defineMachineModel() { + var useTCPC = getProperty("useTCPC"); + switch (getProperty("machineModel")) { + case "umc-500": + var axis1 = createAxis({coordinate:1, table:true, axis:[0, 1, 0], range:[-35, 120], preference:1, tcp:useTCPC}); + var axis2 = createAxis({coordinate:2, table:true, axis:[0, 0, 1], cyclic:true, preference:0, reset:1, tcp:useTCPC}); + machineConfiguration = new MachineConfiguration(axis1, axis2); + machineConfiguration.setHomePositionX(toPreciseUnit(-23.96, IN)); + machineConfiguration.setHomePositionY(toPreciseUnit(-3.37, IN)); + machineConfiguration.setRetractPlane(toPreciseUnit(0, IN)); + maximumSpindleRPM = 8100; + break; + case "umc-750": + var axis1 = createAxis({coordinate:1, table:true, axis:[0, 1, 0], range:[-35, 120], preference:1, tcp:useTCPC}); + var axis2 = createAxis({coordinate:2, table:true, axis:[0, 0, 1], cyclic:true, preference:0, reset:1, tcp:useTCPC}); + machineConfiguration = new MachineConfiguration(axis1, axis2); + machineConfiguration.setHomePositionX(toPreciseUnit(-29.0, IN)); + machineConfiguration.setHomePositionY(toPreciseUnit(-8, IN)); + machineConfiguration.setRetractPlane(toPreciseUnit(2.5, IN)); + maximumSpindleRPM = 8100; + break; + case "umc-1000": + var axis1 = createAxis({coordinate:1, table:true, axis:[0, 1, 0], range:[-35, 120], preference:1, tcp:useTCPC}); + var axis2 = createAxis({coordinate:2, table:true, axis:[0, 0, 1], cyclic:true, preference:0, reset:1, tcp:useTCPC}); + machineConfiguration = new MachineConfiguration(axis1, axis2); + machineConfiguration.setHomePositionX(toPreciseUnit(-40.07, IN)); + machineConfiguration.setHomePositionY(toPreciseUnit(-10.76, IN)); + machineConfiguration.setRetractPlane(toPreciseUnit(0, IN)); + maximumSpindleRPM = 8100; + break; + case "umc-1600": + var axis1 = createAxis({coordinate:1, table:true, axis:[0, 1, 0], range:[-120, 120], preference:1, tcp:useTCPC}); + var axis2 = createAxis({coordinate:2, table:true, axis:[0, 0, 1], cyclic:true, preference:0, reset:1, tcp:useTCPC}); + machineConfiguration = new MachineConfiguration(axis1, axis2); + machineConfiguration.setHomePositionX(toPreciseUnit(0, IN)); + machineConfiguration.setHomePositionY(toPreciseUnit(0, IN)); + machineConfiguration.setRetractPlane(toPreciseUnit(0, IN)); + maximumSpindleRPM = 7500; + break; + } + machineConfiguration.setModel(getProperty("machineModel").toUpperCase()); + machineConfiguration.setVendor("Haas Automation"); + + setMachineConfiguration(machineConfiguration); + if (receivedMachineConfiguration) { + warning(localize("The provided CAM machine configuration is overwritten by the postprocessor.")); + receivedMachineConfiguration = false; // CAM provided machine configuration is overwritten + } +} + +// Start of machine configuration logic +var compensateToolLength = false; // add the tool length to the pivot distance for nonTCP rotary heads +var virtualTooltip = false; // translate the pivot point to the virtual tool tip for nonTCP rotary heads +// internal variables, do not change +var receivedMachineConfiguration; +var tcpIsSupported; + +function activateMachine() { + // determine if TCP is supported by the machine + tcpIsSupported = false; + var axes = [machineConfiguration.getAxisU(), machineConfiguration.getAxisV(), machineConfiguration.getAxisW()]; + for (var i in axes) { + if (axes[i].isEnabled() && axes[i].isTCPEnabled()) { + tcpIsSupported = true; + break; + } + } + + // setup usage of multiAxisFeatures + useMultiAxisFeatures = getProperty("useMultiAxisFeatures") != undefined ? getProperty("useMultiAxisFeatures") : + (typeof useMultiAxisFeatures != "undefined" ? useMultiAxisFeatures : false); + useABCPrepositioning = getProperty("useABCPrepositioning") != undefined ? getProperty("useABCPrepositioning") : + (typeof useABCPrepositioning != "undefined" ? useABCPrepositioning : false); + + 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(); + } + + if (!machineConfiguration.isMultiAxisConfiguration()) { + return; // don't need to modify any settings for 3-axis machines + } + + // retract/reconfigure + safeRetractDistance = getProperty("safeRetractDistance") != undefined ? getProperty("safeRetractDistance") : + (typeof safeRetractDistance == "number" ? safeRetractDistance : 0); + if (machineConfiguration.performRewinds() || (typeof performRewinds == "undefined" ? false : performRewinds)) { + machineConfiguration.enableMachineRewinds(); // enables the rewind/reconfigure logic + if (typeof stockExpansion != "undefined") { + machineConfiguration.setRewindStockExpansion(stockExpansion); + if (!receivedMachineConfiguration) { + setMachineConfiguration(machineConfiguration); + } + } + } + + if (machineConfiguration.isHeadConfiguration()) { + compensateToolLength = typeof compensateToolLength == "undefined" ? false : compensateToolLength; + virtualTooltip = typeof virtualTooltip == "undefined" ? false : virtualTooltip; + machineConfiguration.setVirtualTooltip(virtualTooltip); + } + setFeedrateMode(); + + if (machineConfiguration.isHeadConfiguration() && compensateToolLength) { + for (var i = 0; i < getNumberOfSections(); ++i) { + var section = getSection(i); + if (section.isMultiAxis()) { + machineConfiguration.setToolLength(section.getTool().getBodyLength()); // define the tool length for head adjustments + section.optimizeMachineAnglesByMachine(machineConfiguration, OPTIMIZE_AXIS); + } + } + } else { + optimizeMachineAngles2(OPTIMIZE_AXIS); + } +} + +function setFeedrateMode(reset) { + if ((tcpIsSupported && !reset) || !machineConfiguration.isMultiAxisConfiguration()) { + return; + } + machineConfiguration.setMultiAxisFeedrate( + tcpIsSupported ? FEED_FPM : getProperty("useDPMFeeds") ? FEED_DPM : FEED_INVERSE_TIME, + 9999.99, // maximum output value for inverse time feed rates + INVERSE_MINUTES, // can be INVERSE_SECONDS or DPM_COMBINATION for DPM feeds + 0.5, // tolerance to determine when the DPM feed has changed + 1.0 // ratio of rotary accuracy to linear accuracy for DPM calculations + ); + if (!receivedMachineConfiguration || (revision < 45765)) { + setMachineConfiguration(machineConfiguration); + } +} + +function defineMachine() { + hasA = getProperty("hasAAxis") != "false"; + hasB = getProperty("hasBAxis") != "false"; + hasC = getProperty("hasCAxis") != "false"; + + if (hasA && hasB && hasC) { + error(localize("Only two rotary axes can be active at the same time.")); + return; + } else if ((hasA || hasB || hasC) && getProperty("machineModel") != "none") { + error(localize("You can only select either a machine model or use the ABC axis properties.")); + return; + } else if (((hasA || hasB || hasC) || getProperty("machineModel") != "none") && (receivedMachineConfiguration && machineConfiguration.isMultiAxisConfiguration())) { + error(localize("You can only select either a machine in the CAM setup or use the properties to define your kinematics.")); + return; + } + if (getProperty("machineModel") == "none") { + if (hasA || hasB || hasC) { // configure machine + var aAxis; + var bAxis; + var cAxis; + var useTCPC = getProperty("useTCPC"); + if (hasA) { // A Axis - For horizontal machines and trunnions + var dir = getProperty("hasAAxis") == "reversed" ? -1 : 1; + if (hasC || hasB) { + var aMin = (dir == 1) ? -120 - 0.0001 : -30 - 0.0001; + var aMax = (dir == 1) ? 30 + 0.0001 : 120 + 0.0001; + aAxis = createAxis({coordinate:0, table:true, axis:[dir, 0, 0], range:[aMin, aMax], preference:dir, reset:(hasB ? 0 : 1), tcp:useTCPC}); + } else { + aAxis = createAxis({coordinate:0, table:true, axis:[dir, 0, 0], cyclic:true, tcp:useTCPC}); + } + } + + if (hasB) { // B Axis - For horizontal machines and trunnions + var dir = getProperty("hasBAxis") == "reversed" ? -1 : 1; + if (hasC) { + var bMin = (dir == 1) ? -120 - 0.0001 : -30 - 0.0001; + var bMax = (dir == 1) ? 30 + 0.0001 : 120 + 0.0001; + bAxis = createAxis({coordinate:1, table:true, axis:[0, dir, 0], range:[bMin, bMax], preference:-dir, reset:1, tcp:useTCPC}); + } else if (hasA) { + bAxis = createAxis({coordinate:1, table:true, axis:[0, 0, dir], cyclic:true, tcp:useTCPC}); + } else { + bAxis = createAxis({coordinate:1, table:true, axis:[0, dir, 0], cyclic:true, tcp:useTCPC}); + } + } + + if (hasC) { // C Axis - For trunnions only + var dir = getProperty("hasCAxis") == "reversed" ? -1 : 1; + cAxis = createAxis({coordinate:2, table:true, axis:[0, 0, dir], cyclic:true, reset:1, tcp:useTCPC}); + } + + if (hasA && hasC) { // AC trunnion + machineConfiguration = new MachineConfiguration(aAxis, cAxis); + } else if (hasB && hasC) { // BC trunnion + machineConfiguration = new MachineConfiguration(bAxis, cAxis); + } else if (hasA && hasB) { // AB trunnion + machineConfiguration = new MachineConfiguration(aAxis, bAxis); + } else if (hasA) { // A rotary + machineConfiguration = new MachineConfiguration(aAxis); + } else if (hasB) { // B rotary - horizontal machine only + machineConfiguration = new MachineConfiguration(bAxis); + } else if (hasC) { // C rotary + machineConfiguration = new MachineConfiguration(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 + } + } + } else { + defineMachineModel(); + } + /* home positions */ + // machineConfiguration.setHomePositionX(toPreciseUnit(0, IN)); + // machineConfiguration.setHomePositionY(toPreciseUnit(0, IN)); + // machineConfiguration.setRetractPlane(toPreciseUnit(0, IN)); +} +// End of machine configuration logic + +function onOpen() { + receivedMachineConfiguration = (typeof machineConfiguration.isReceived == "function") ? machineConfiguration.isReceived() : + ((machineConfiguration.getDescription() != "") || machineConfiguration.isMultiAxisConfiguration()); + if (typeof defineMachine == "function") { + defineMachine(); // hardcoded machine configuration + } + activateMachine(); // enable the machine optimizations and settings + + if (getProperty("useDPMFeeds")) { + gFeedModeModal.format(94); + } + if (getProperty("useRadius")) { + maximumCircularSweep = toRad(90); // avoid potential center calculation errors for CNC + } + if (getProperty("sequenceNumberOnlyOnToolChange")) { + setProperty("showSequenceNumbers", false); + } + if (!getProperty("useDWO")) { + useDwoForPositioning = false; + } + + gRotationModal.format(69); // Default to G69 Rotation Off + + if (toPreciseUnit(highFeedrate, MM) <= 0) { + error(localize("You must set 'highFeedrate' because axes are not synchronized for rapid traversal.")); + return; + } + + if (!getProperty("separateWordsWithSpace")) { + setWordSeparator(""); + } + saveShowSequenceNumbers = getProperty("showSequenceNumbers"); + sequenceNumber = getProperty("sequenceNumberStart"); + writeln("%"); + + if (programName) { + var programId; + try { + programId = getAsInt(programName); + } catch (e) { + error(localize("Program name must be a number.")); + return; + } + if (!((programId >= 1) && (programId <= 99999))) { + error(localize("Program number is out of range.")); + return; + } + writeln( + "O" + oFormat.format(programId) + + conditional(programComment, " " + formatComment(programComment.substr(0, maximumLineLength - 2 - ("O" + oFormat.format(programId)).length - 1))) + ); + lastSubprogram = (initialSubprogramNumber - 1); + } else { + error(localize("Program name has not been specified.")); + return; + } + + if (getProperty("useG0")) { + writeComment(localize("Using G0 which travels along dogleg path.")); + } else { + writeComment(subst(localize("Using high feed G1 F%1 instead of G0."), feedFormat.format(toPreciseUnit(highFeedrate, MM)))); + } + + if (getProperty("writeVersion")) { + if ((typeof getHeaderVersion == "function") && getHeaderVersion()) { + writeComment(localize("post version") + ": " + getHeaderVersion()); + } + if ((typeof getHeaderDate == "function") && getHeaderDate()) { + writeComment(localize("post modified") + ": " + getHeaderDate()); + } + } + + // dump machine configuration + var vendor = machineConfiguration.getVendor(); + var model = machineConfiguration.getModel(); + var description = machineConfiguration.getDescription(); + + if (getProperty("writeMachine") && (vendor || model || description)) { + writeComment(localize("Machine")); + if (vendor) { + writeComment(" " + localize("vendor") + ": " + vendor); + } + if (model) { + writeComment(" " + localize("model") + ": " + model); + } + if (description) { + writeComment(" " + localize("description") + ": " + description); + } + } + + // dump tool information + if (getProperty("writeTools")) { + var zRanges = {}; + if (is3D()) { + var numberOfSections = getNumberOfSections(); + for (var i = 0; i < numberOfSections; ++i) { + var section = getSection(i); + var zRange = section.getGlobalZRange(); + var tool = section.getTool(); + if (zRanges[tool.number]) { + zRanges[tool.number].expandToRange(zRange); + } else { + zRanges[tool.number] = zRange; + } + } + } + + var tools = getToolTable(); + if (tools.getNumberOfTools() > 0) { + for (var i = 0; i < tools.getNumberOfTools(); ++i) { + var tool = tools.getTool(i); + var comment = "T" + toolFormat.format(tool.number) + " " + + "D=" + xyzFormat.format(tool.diameter) + " " + + localize("CR") + "=" + xyzFormat.format(tool.cornerRadius); + if ((tool.taperAngle > 0) && (tool.taperAngle < Math.PI)) { + comment += " " + localize("TAPER") + "=" + taperFormat.format(tool.taperAngle) + localize("deg"); + } + if (zRanges[tool.number]) { + comment += " - " + localize("ZMIN") + "=" + xyzFormat.format(zRanges[tool.number].getMinimum()); + } + comment += " - " + getToolTypeName(tool.type); + writeComment(comment); + + if (getProperty("useM130ToolImages")) { + var toolRenderer = createToolRenderer(); + if (toolRenderer) { + toolRenderer.setBackgroundColor(new Color(1, 1, 1)); + toolRenderer.setFluteColor(new Color(40.0 / 255, 40.0 / 255, 40.0 / 255)); + toolRenderer.setShoulderColor(new Color(80.0 / 255, 80.0 / 255, 80.0 / 255)); + toolRenderer.setShaftColor(new Color(80.0 / 255, 80.0 / 255, 80.0 / 255)); + toolRenderer.setHolderColor(new Color(40.0 / 255, 40.0 / 255, 40.0 / 255)); + if (i % 2 == 0) { + toolRenderer.setBackgroundColor(new Color(1, 1, 1)); + } else { + toolRenderer.setBackgroundColor(new Color(240 / 255.0, 240 / 255.0, 240 / 255.0)); + } + var path = "tool" + tool.number + ".png"; + var width = 400; + var height = 532; + toolRenderer.exportAs(path, "image/png", tool, width, height); + } + } + } + } + } + + // optionally cycle through all tools + if (getProperty("optionallyCycleToolsAtStart") || getProperty("optionallyMeasureToolsAtStart")) { + var tools = getToolTable(); + if (tools.getNumberOfTools() > 0) { + writeln(""); + + writeOptionalBlock(mFormat.format(0), formatComment(localize("Read note"))); // wait for operator + writeComment(localize("With BLOCK DELETE turned off each tool will cycle through")); + writeComment(localize("the spindle to verify that the correct tool is in the tool magazine")); + if (getProperty("optionallyMeasureToolsAtStart")) { + writeComment(localize("and to automatically measure it")); + } + writeComment(localize("Once the tools are verified turn BLOCK DELETE on to skip verification")); + + for (var i = 0; i < tools.getNumberOfTools(); ++i) { + var tool = tools.getTool(i); + if (getProperty("optionallyMeasureToolsAtStart") && (tool.type == TOOL_PROBE)) { + continue; + } + var comment = "T" + toolFormat.format(tool.number) + " " + + "D=" + xyzFormat.format(tool.diameter) + " " + + localize("CR") + "=" + xyzFormat.format(tool.cornerRadius); + if ((tool.taperAngle > 0) && (tool.taperAngle < Math.PI)) { + comment += " " + localize("TAPER") + "=" + taperFormat.format(tool.taperAngle) + localize("deg"); + } + comment += " - " + getToolTypeName(tool.type); + writeComment(comment); + if (getProperty("optionallyMeasureToolsAtStart")) { + writeToolMeasureBlock(tool, true); + } else { + writeToolCycleBlock(tool); + } + } + } + writeln(""); + } + + if (false /*getProperty("useDWO")*/) { + var failed = false; + var dynamicWCSs = {}; + for (var i = 0; i < getNumberOfSections(); ++i) { + var section = getSection(i); + var description = section.hasParameter("operation-comment") ? section.getParameter("operation-comment") : ("#" + (i + 1)); + if (!section.hasDynamicWorkOffset()) { + error(subst(localize("Dynamic work offset has not been set for operation '%1'."), description)); + failed = true; + } + + var o = section.getDynamicWCSOrigin(); + var p = section.getDynamicWCSPlane(); + if (dynamicWCSs[section.getDynamicWorkOffset()]) { + if ((Vector.diff(o, dynamicWCSs[section.getDynamicWorkOffset()].origin).length > 1e-9) || + (Matrix.diff(p, dynamicWCSs[section.getDynamicWorkOffset()].plane).n1 > 1e-9)) { + error(subst(localize("Dynamic WCS mismatch for operation '%1'."), description)); + failed = true; + } + } else { + dynamicWCSs[section.getDynamicWorkOffset()] = {origin:o, plane:p}; + } + } + if (failed) { + return; + } + } + + if (false) { + // check for duplicate tool number + for (var i = 0; i < getNumberOfSections(); ++i) { + var sectioni = getSection(i); + var tooli = sectioni.getTool(); + for (var j = i + 1; j < getNumberOfSections(); ++j) { + var sectionj = getSection(j); + var toolj = sectionj.getTool(); + if (tooli.number == toolj.number) { + if (xyzFormat.areDifferent(tooli.diameter, toolj.diameter) || + xyzFormat.areDifferent(tooli.cornerRadius, toolj.cornerRadius) || + abcFormat.areDifferent(tooli.taperAngle, toolj.taperAngle) || + (tooli.numberOfFlutes != toolj.numberOfFlutes)) { + error( + subst( + localize("Using the same tool number for different cutter geometry for operation '%1' and '%2'."), + sectioni.hasParameter("operation-comment") ? sectioni.getParameter("operation-comment") : ("#" + (i + 1)), + sectionj.hasParameter("operation-comment") ? sectionj.getParameter("operation-comment") : ("#" + (j + 1)) + ) + ); + return; + } + } + } + } + } + + if ((getNumberOfSections() > 0) && (getSection(0).workOffset == 0)) { + for (var i = 0; i < getNumberOfSections(); ++i) { + if (getSection(i).workOffset > 0) { + error(localize("Using multiple work offsets is not possible if the initial work offset is 0.")); + return; + } + } + } + + // absolute coordinates and feed per min + writeBlock(gAbsIncModal.format(90), gFeedModeModal.format(94), gPlaneModal.format(17)); + + switch (unit) { + case IN: + writeBlock(gUnitModal.format(20)); + break; + case MM: + writeBlock(gUnitModal.format(21)); + break; + } + + coolantPressure = getProperty("coolantPressure"); + + if (getProperty("chipTransport")) { + onCommand(COMMAND_START_CHIP_TRANSPORT); + } + // Probing Surface Inspection + if (typeof inspectionWriteVariables == "function") { + inspectionWriteVariables(); + } +} + +function onComment(message) { + writeComment(message); +} + +/** Force output of X, Y, and Z. */ +function forceXYZ() { + xOutput.reset(); + yOutput.reset(); + zOutput.reset(); +} + +/** Force output of A, B, and C. */ +function forceABC() { + aOutput.reset(); + bOutput.reset(); + cOutput.reset(); +} + +function forceFeed() { + currentFeedId = undefined; + feedOutput.reset(); +} + +/** Force output of X, Y, Z, A, B, C, and F on next output. */ +function forceAny() { + forceXYZ(); + forceABC(); + forceFeed(); +} + +var lengthCompensationActive = false; +/** Disables length compensation if currently active or if forced. */ +function disableLengthCompensation(force, message) { + if (lengthCompensationActive || force) { + writeBlock(gFormat.format(49), conditional(message, formatComment(message))); + lengthCompensationActive = false; + } +} + +function writeG187() { + if (hasParameter("operation-strategy") && (getParameter("operation-strategy") == "drill")) { + writeBlock(gFormat.format(187)); // reset G187 setting to machine default + } else if (hasParameter("operation:tolerance")) { + var tolerance = Math.max(getParameter("operation:tolerance"), 0); + if (tolerance > 0) { + var stockToLeaveThreshold = toUnit(0.1, MM); + var stockToLeave = 0; + var verticalStockToLeave = 0; + if (hasParameter("operation:stockToLeave")) { + stockToLeave = xyzFormat.getResultingValue(getParameter("operation:stockToLeave")); + } + if (hasParameter("operation:verticalStockToLeave")) { + verticalStockToLeave = xyzFormat.getResultingValue(getParameter("operation:verticalStockToLeave")); + } + + var workMode; + if (((stockToLeave > stockToLeaveThreshold) && (verticalStockToLeave > stockToLeaveThreshold)) || + (hasParameter("operation:strategy") && getParameter("operation:strategy") == "face")) { + workMode = 1; // roughing + } else { + if ((stockToLeave > 0) || (verticalStockToLeave > 0)) { + workMode = 2; // default + } else { + workMode = 3; // fine + } + } + writeBlock(gFormat.format(187), "P" + workMode); // set tolerance mode + // writeBlock(gFormat.format(187), "P" + workMode, "E" + xyzFormat.format(tolerance)); // set tolerance mode + } else { + writeBlock(gFormat.format(187)); // reset G187 setting to machine default + } + } else { + writeBlock(gFormat.format(187)); // reset G187 setting to machine default + } +} + +function FeedContext(id, description, feed) { + this.id = id; + this.description = description; + this.feed = feed; +} + +function getFeed(f) { + if (activeMovements) { + var feedContext = activeMovements[movement]; + if (feedContext != undefined) { + if (!feedFormat.areDifferent(feedContext.feed, f)) { + if (feedContext.id == currentFeedId) { + return ""; // nothing has changed + } + forceFeed(); + currentFeedId = feedContext.id; + return "F#" + (firstFeedParameter + feedContext.id); + } + } + currentFeedId = undefined; // force Q feed next time + } + return feedOutput.format(f); // use feed value +} + +function initializeActiveFeeds() { + activeMovements = new Array(); + var movements = currentSection.getMovements(); + + var id = 0; + var activeFeeds = new Array(); + if (hasParameter("operation:tool_feedCutting")) { + if (movements & ((1 << MOVEMENT_CUTTING) | (1 << MOVEMENT_LINK_TRANSITION) | (1 << MOVEMENT_EXTENDED))) { + var feedContext = new FeedContext(id, localize("Cutting"), getParameter("operation:tool_feedCutting")); + activeFeeds.push(feedContext); + activeMovements[MOVEMENT_CUTTING] = feedContext; + activeMovements[MOVEMENT_LINK_TRANSITION] = feedContext; + activeMovements[MOVEMENT_EXTENDED] = feedContext; + } + ++id; + if (movements & (1 << MOVEMENT_PREDRILL)) { + feedContext = new FeedContext(id, localize("Predrilling"), getParameter("operation:tool_feedCutting")); + activeMovements[MOVEMENT_PREDRILL] = feedContext; + activeFeeds.push(feedContext); + } + ++id; + } + + if (hasParameter("operation:finishFeedrate")) { + if (movements & (1 << MOVEMENT_FINISH_CUTTING)) { + var feedContext = new FeedContext(id, localize("Finish"), getParameter("operation:finishFeedrate")); + activeFeeds.push(feedContext); + activeMovements[MOVEMENT_FINISH_CUTTING] = feedContext; + } + ++id; + } else if (hasParameter("operation:tool_feedCutting")) { + if (movements & (1 << MOVEMENT_FINISH_CUTTING)) { + var feedContext = new FeedContext(id, localize("Finish"), getParameter("operation:tool_feedCutting")); + activeFeeds.push(feedContext); + activeMovements[MOVEMENT_FINISH_CUTTING] = feedContext; + } + ++id; + } + + if (hasParameter("operation:tool_feedEntry")) { + if (movements & (1 << MOVEMENT_LEAD_IN)) { + var feedContext = new FeedContext(id, localize("Entry"), getParameter("operation:tool_feedEntry")); + activeFeeds.push(feedContext); + activeMovements[MOVEMENT_LEAD_IN] = feedContext; + } + ++id; + } + + if (hasParameter("operation:tool_feedExit")) { + if (movements & (1 << MOVEMENT_LEAD_OUT)) { + var feedContext = new FeedContext(id, localize("Exit"), getParameter("operation:tool_feedExit")); + activeFeeds.push(feedContext); + activeMovements[MOVEMENT_LEAD_OUT] = feedContext; + } + ++id; + } + + if (hasParameter("operation:noEngagementFeedrate")) { + if (movements & (1 << MOVEMENT_LINK_DIRECT)) { + var feedContext = new FeedContext(id, localize("Direct"), getParameter("operation:noEngagementFeedrate")); + activeFeeds.push(feedContext); + activeMovements[MOVEMENT_LINK_DIRECT] = feedContext; + } + ++id; + } else if (hasParameter("operation:tool_feedCutting") && + hasParameter("operation:tool_feedEntry") && + hasParameter("operation:tool_feedExit")) { + if (movements & (1 << MOVEMENT_LINK_DIRECT)) { + var feedContext = new FeedContext(id, localize("Direct"), Math.max(getParameter("operation:tool_feedCutting"), getParameter("operation:tool_feedEntry"), getParameter("operation:tool_feedExit"))); + activeFeeds.push(feedContext); + activeMovements[MOVEMENT_LINK_DIRECT] = feedContext; + } + ++id; + } + + if (hasParameter("operation:reducedFeedrate")) { + if (movements & (1 << MOVEMENT_REDUCED)) { + var feedContext = new FeedContext(id, localize("Reduced"), getParameter("operation:reducedFeedrate")); + activeFeeds.push(feedContext); + activeMovements[MOVEMENT_REDUCED] = feedContext; + } + ++id; + } + + if (hasParameter("operation:tool_feedRamp")) { + if (movements & ((1 << MOVEMENT_RAMP) | (1 << MOVEMENT_RAMP_HELIX) | (1 << MOVEMENT_RAMP_PROFILE) | (1 << MOVEMENT_RAMP_ZIG_ZAG))) { + var feedContext = new FeedContext(id, localize("Ramping"), getParameter("operation:tool_feedRamp")); + activeFeeds.push(feedContext); + activeMovements[MOVEMENT_RAMP] = feedContext; + activeMovements[MOVEMENT_RAMP_HELIX] = feedContext; + activeMovements[MOVEMENT_RAMP_PROFILE] = feedContext; + activeMovements[MOVEMENT_RAMP_ZIG_ZAG] = feedContext; + } + ++id; + } + if (hasParameter("operation:tool_feedPlunge")) { + if (movements & (1 << MOVEMENT_PLUNGE)) { + var feedContext = new FeedContext(id, localize("Plunge"), getParameter("operation:tool_feedPlunge")); + activeFeeds.push(feedContext); + activeMovements[MOVEMENT_PLUNGE] = feedContext; + } + ++id; + } + if (true) { // high feed + if ((movements & (1 << MOVEMENT_HIGH_FEED)) || (highFeedMapping != HIGH_FEED_NO_MAPPING)) { + var feed; + if (hasParameter("operation:highFeedrateMode") && getParameter("operation:highFeedrateMode") != "disabled") { + feed = getParameter("operation:highFeedrate"); + } else { + feed = toPreciseUnit(this.highFeedrate, MM); + } + var feedContext = new FeedContext(id, localize("High Feed"), feed); + activeFeeds.push(feedContext); + activeMovements[MOVEMENT_HIGH_FEED] = feedContext; + activeMovements[MOVEMENT_RAPID] = feedContext; + } + ++id; + } + + for (var i = 0; i < activeFeeds.length; ++i) { + var feedContext = activeFeeds[i]; + writeBlock("#" + (firstFeedParameter + feedContext.id) + "=" + feedFormat.format(feedContext.feed), formatComment(feedContext.description)); + } +} + +var currentWorkPlaneABC = undefined; +var activeG254 = false; + +function forceWorkPlane() { + currentWorkPlaneABC = undefined; +} + +function defineWorkPlane(_section, _setWorkPlane) { + var abc = new Vector(0, 0, 0); + if (machineConfiguration.isMultiAxisConfiguration()) { // use 5-axis indexing for multi-axis mode + // set working plane after datum shift + + if (_section.isMultiAxis()) { + cancelTransformation(); + abc = _section.getInitialToolAxisABC(); + if (_setWorkPlane) { + if (activeG254) { + writeBlock(gFormat.format(255)); // cancel DWO + activeG254 = false; + } + if (!retracted) { + moveToSafeRetractPosition(); + } + forceWorkPlane(); + onCommand(COMMAND_UNLOCK_MULTI_AXIS); + gMotionModal.reset(); + writeBlock( + gMotionModal.format(0), + conditional(machineConfiguration.isMachineCoordinate(0), "A" + abcFormat.format(abc.x)), + conditional(machineConfiguration.isMachineCoordinate(1), "B" + abcFormat.format(abc.y)), + conditional(machineConfiguration.isMachineCoordinate(2), "C" + abcFormat.format(abc.z)) + ); + } + } else { + abc = getWorkPlaneMachineABC(_section.workPlane, _setWorkPlane); + if (_setWorkPlane) { + setWorkPlane(abc); + } + } + } else { // pure 3D + var remaining = _section.workPlane; + if (!isSameDirection(remaining.forward, new Vector(0, 0, 1))) { + error(localize("Tool orientation is not supported.")); + return abc; + } + setRotation(remaining); + } + return abc; +} + +function setWorkPlane(abc) { + if (!machineConfiguration.isMultiAxisConfiguration()) { + return; // ignore + } + + var _skipBlock = false; + if (!((currentWorkPlaneABC == undefined) || + abcFormat.areDifferent(abc.x, currentWorkPlaneABC.x) || + abcFormat.areDifferent(abc.y, currentWorkPlaneABC.y) || + abcFormat.areDifferent(abc.z, currentWorkPlaneABC.z))) { + if (operationNeedsSafeStart) { + _skipBlock = true; + } else { + return; // no change + } + } + skipBlock = _skipBlock; + onCommand(COMMAND_UNLOCK_MULTI_AXIS); + + if (!retracted) { + skipBlock = _skipBlock; + moveToSafeRetractPosition(false); + } + + if (activeG254) { + skipBlock = _skipBlock; + activeG254 = false; + writeBlock(gFormat.format(255)); // cancel DWO + } + + gMotionModal.reset(); + skipBlock = _skipBlock; + writeBlock( + gMotionModal.format(0), + conditional(machineConfiguration.isMachineCoordinate(0), "A" + abcFormat.format(abc.x)), + conditional(machineConfiguration.isMachineCoordinate(1), "B" + abcFormat.format(abc.y)), + conditional(machineConfiguration.isMachineCoordinate(2), "C" + abcFormat.format(abc.z)) + ); + + skipBlock = _skipBlock; + onCommand(COMMAND_LOCK_MULTI_AXIS); + + if (getProperty("useDWO") && + (abcFormat.isSignificant(abc.x % (Math.PI * 2)) || abcFormat.isSignificant(abc.y % (Math.PI * 2)) || abcFormat.isSignificant(abc.z % (Math.PI * 2)))) { + skipBlock = _skipBlock; + activeG254 = true; + writeBlock(gFormat.format(254)); // enable DWO + } + + setCurrentABC(abc); // required for machine simulation + currentWorkPlaneABC = abc; +} + +var closestABC = true; // choose closest machine angles +var currentMachineABC = new Vector(0, 0, 0); + +function getPreferenceWeight(_abc) { + var axis = new Array(machineConfiguration.getAxisU(), machineConfiguration.getAxisV(), machineConfiguration.getAxisW()); + var abc = new Array(_abc.x, _abc.y, _abc.z); + var preference = 0; + for (var i = 0; i < 3; ++i) { + if (axis[i].isEnabled()) { + preference += ((abcFormat.getResultingValue(abc[axis[i].getCoordinate()]) * axis[i].getPreference()) < 0) ? -1 : 1; + } + } + return preference; +} + +function remapToABC(currentABC, previousABC) { + var both = machineConfiguration.getABCByDirectionBoth(machineConfiguration.getDirection(currentABC)); + var abc1 = machineConfiguration.remapToABC(both[0], previousABC); + abc1 = machineConfiguration.remapABC(abc1); + var abc2 = machineConfiguration.remapToABC(both[1], previousABC); + abc2 = machineConfiguration.remapABC(abc2); + + // choose angles based on preference + var preference1 = getPreferenceWeight(abc1); + var preference2 = getPreferenceWeight(abc2); + if (preference1 > preference2) { + return abc1; + } else if (preference2 > preference1) { + return abc2; + } + + // choose angles based on closest solution + if (Vector.diff(abc1, previousABC).length < Vector.diff(abc2, previousABC).length) { + return abc1; + } else { + return abc2; + } +} + +function getWorkPlaneMachineABC(workPlane, _setWorkPlane) { + var W = workPlane; // map to global frame + + var abc = machineConfiguration.getABC(W); + if (closestABC) { + if (currentMachineABC) { + abc = remapToABC(abc, currentMachineABC); + } else { + abc = machineConfiguration.getPreferredABC(abc); + } + } else { + abc = machineConfiguration.getPreferredABC(abc); + } + + try { + abc = machineConfiguration.remapABC(abc); + if (_setWorkPlane) { + currentMachineABC = abc; + } + } catch (e) { + error( + localize("Machine angles not supported") + ":" + + conditional(machineConfiguration.isMachineCoordinate(0), " A" + abcFormat.format(abc.x)) + + conditional(machineConfiguration.isMachineCoordinate(1), " B" + abcFormat.format(abc.y)) + + conditional(machineConfiguration.isMachineCoordinate(2), " C" + abcFormat.format(abc.z)) + ); + } + + var direction = machineConfiguration.getDirection(abc); + if (!isSameDirection(direction, W.forward)) { + error(localize("Orientation not supported.")); + } + + if (!machineConfiguration.isABCSupported(abc)) { + error( + localize("Work plane is not supported") + ":" + + conditional(machineConfiguration.isMachineCoordinate(0), " A" + abcFormat.format(abc.x)) + + conditional(machineConfiguration.isMachineCoordinate(1), " B" + abcFormat.format(abc.y)) + + conditional(machineConfiguration.isMachineCoordinate(2), " C" + abcFormat.format(abc.z)) + ); + } + + var tcp = false; + if (tcp) { + setRotation(W); // TCP mode + } else { + var O = machineConfiguration.getOrientation(abc); + var R = machineConfiguration.getRemainingOrientation(abc, W); + setRotation(R); + } + + return abc; +} + +function printProbeResults() { + return currentSection.getParameter("printResults", 0) == 1; +} + +var probeOutputWorkOffset = 1; + +function onPassThrough(text) { + var commands = String(text).split(","); + for (text in commands) { + writeBlock(commands[text]); + } +} + +function onManualNC(command, value) { + switch (command) { + case COMMAND_ACTION: + if (String(value).toUpperCase() == "CYCLE_REVERSAL") { + cycleReverse = true; + } else if (String(value).toUpperCase() == "VFD_LOW") { + coolantPressure = "P0"; + } else if (String(value).toUpperCase() == "VFD_NORMAL") { + coolantPressure = "P1"; + } else if (String(value).toUpperCase() == "VFD_HIGH") { + coolantPressure = "P2"; + } else if (String(value).toUpperCase() == "USEPOLARMODE") { + usePolarMode = true; + } + break; + default: + expandManualNC(command, value); + } +} + +function onParameter(name, value) { + if (name == "probe-output-work-offset") { + probeOutputWorkOffset = (value > 0) ? value : 1; + } +} + +var seenPatternIds = {}; + +function previewImage() { + var permittedExtensions = ["JPG", "MP4", "MOV", "PNG", "JPEG"]; + var patternId = currentSection.getPatternId(); + var show = false; + if (!seenPatternIds[patternId]) { + show = true; + seenPatternIds[patternId] = true; + } + var images = []; + if (show) { + if (FileSystem.isFile(FileSystem.getCombinedPath(FileSystem.getFolderPath(getOutputPath()), modelImagePath))) { + images.push(modelImagePath); + } + if (hasParameter("autodeskcam:preview-name") && FileSystem.isFile(FileSystem.getCombinedPath(FileSystem.getFolderPath(getOutputPath()), getParameter("autodeskcam:preview-name")))) { + images.push(getParameter("autodeskcam:preview-name")); + } + + for (var i = 0; i < images.length; ++i) { + var fileExtension = images[i].slice(images[i].lastIndexOf(".") + 1, images[i].length).toUpperCase(); + var permittedExtension = false; + for (var j = 0; j < permittedExtensions.length; ++j) { + if (fileExtension == permittedExtensions[j]) { + permittedExtension = true; + break; // found + } + } + if (!permittedExtension) { + warning(localize("The image file format " + "\"" + fileExtension + "\"" + " is not supported on HAAS controls.")); + } + + if (!getProperty("useM130PartImages") || !permittedExtension) { + FileSystem.remove(FileSystem.getCombinedPath(FileSystem.getFolderPath(getOutputPath()), images[i])); // remove + images.splice([i], 1); // remove from array + } + } + if (images.length > 0) { + writeBlock(mFormat.format(130), "(" + images[images.length - 1] + ")"); + } + } +} + +/** Returns true if the spatial vectors are significantly different. */ +function areSpatialVectorsDifferent(_vector1, _vector2) { + return (xyzFormat.getResultingValue(_vector1.x) != xyzFormat.getResultingValue(_vector2.x)) || + (xyzFormat.getResultingValue(_vector1.y) != xyzFormat.getResultingValue(_vector2.y)) || + (xyzFormat.getResultingValue(_vector1.z) != xyzFormat.getResultingValue(_vector2.z)); +} + +/** Returns true if the spatial boxes are a pure translation. */ +function areSpatialBoxesTranslated(_box1, _box2) { + return !areSpatialVectorsDifferent(Vector.diff(_box1[1], _box1[0]), Vector.diff(_box2[1], _box2[0])) && + !areSpatialVectorsDifferent(Vector.diff(_box2[0], _box1[0]), Vector.diff(_box2[1], _box1[1])); +} + +/** Returns true if the spatial boxes are same. */ +function areSpatialBoxesSame(_box1, _box2) { + return !areSpatialVectorsDifferent(_box1[0], _box2[0]) && !areSpatialVectorsDifferent(_box1[1], _box2[1]); +} + +function subprogramDefine(_initialPosition, _abc, _retracted, _zIsOutput) { + // convert patterns into subprograms + var usePattern = false; + patternIsActive = false; + if (currentSection.isPatterned && currentSection.isPatterned() && (getProperty("useSubroutines") == "patterns")) { + currentPattern = currentSection.getPatternId(); + firstPattern = true; + for (var i = 0; i < definedPatterns.length; ++i) { + if ((definedPatterns[i].patternType == SUB_PATTERN) && (currentPattern == definedPatterns[i].patternId)) { + currentSubprogram = definedPatterns[i].subProgram; + usePattern = definedPatterns[i].validPattern; + firstPattern = false; + break; + } + } + + if (firstPattern) { + // determine if this is a valid pattern for creating a subprogram + usePattern = subprogramIsValid(currentSection, currentPattern, SUB_PATTERN); + if (usePattern) { + currentSubprogram = ++lastSubprogram; + } + definedPatterns.push({ + patternType: SUB_PATTERN, + patternId: currentPattern, + subProgram: currentSubprogram, + validPattern: usePattern, + initialPosition: _initialPosition, + finalPosition: _initialPosition + }); + } + + if (usePattern) { + // make sure Z-position is output prior to subprogram call + if (!_retracted && !_zIsOutput) { + writeBlock(gMotionModal.format(0), zOutput.format(_initialPosition.z)); + } + + // call subprogram + writeBlock(mFormat.format(97), "P" + nFormat.format(currentSubprogram)); + patternIsActive = true; + + if (firstPattern) { + subprogramStart(_initialPosition, _abc, incrementalSubprogram); + } else { + skipRemainingSection(); + setCurrentPosition(getFramePosition(currentSection.getFinalPosition())); + } + } + } + + // Output cycle operation as subprogram + if (!usePattern && (getProperty("useSubroutines") == "cycles") && currentSection.doesStrictCycle && + (currentSection.getNumberOfCycles() == 1) && currentSection.getNumberOfCyclePoints() >= minimumCyclePoints) { + var finalPosition = getFramePosition(currentSection.getFinalPosition()); + currentPattern = currentSection.getNumberOfCyclePoints(); + firstPattern = true; + for (var i = 0; i < definedPatterns.length; ++i) { + if ((definedPatterns[i].patternType == SUB_CYCLE) && (currentPattern == definedPatterns[i].patternId) && + !areSpatialVectorsDifferent(_initialPosition, definedPatterns[i].initialPosition) && + !areSpatialVectorsDifferent(finalPosition, definedPatterns[i].finalPosition)) { + currentSubprogram = definedPatterns[i].subProgram; + usePattern = definedPatterns[i].validPattern; + firstPattern = false; + break; + } + } + + if (firstPattern) { + // determine if this is a valid pattern for creating a subprogram + usePattern = subprogramIsValid(currentSection, currentPattern, SUB_CYCLE); + if (usePattern) { + currentSubprogram = ++lastSubprogram; + } + definedPatterns.push({ + patternType: SUB_CYCLE, + patternId: currentPattern, + subProgram: currentSubprogram, + validPattern: usePattern, + initialPosition: _initialPosition, + finalPosition: finalPosition + }); + } + cycleSubprogramIsActive = usePattern; + } + + // Output each operation as a subprogram + if (!usePattern && (getProperty("useSubroutines") == "allOperations")) { + currentSubprogram = ++lastSubprogram; + writeBlock(mFormat.format(97), "P" + nFormat.format(currentSubprogram)); + firstPattern = true; + subprogramStart(_initialPosition, _abc, false); + } +} + +function subprogramStart(_initialPosition, _abc, _incremental) { + redirectToBuffer(); + var comment = ""; + if (hasParameter("operation-comment")) { + comment = getParameter("operation-comment"); + } + writeln( + "N" + nFormat.format(currentSubprogram) + + conditional(comment, formatComment(comment.substr(0, maximumLineLength - 2 - 6 - 1))) + ); + setProperty("showSequenceNumbers", false); + if (_incremental) { + setIncrementalMode(_initialPosition, _abc); + } + gPlaneModal.reset(); + gMotionModal.reset(); +} + +function subprogramEnd() { + if (firstPattern) { + writeBlock(mFormat.format(99)); + writeln(""); + subprograms += getRedirectionBuffer(); + } + forceAny(); + firstPattern = false; + setProperty("showSequenceNumbers", saveShowSequenceNumbers); + closeRedirection(); +} + +function subprogramIsValid(_section, _patternId, _patternType) { + var sectionId = _section.getId(); + var numberOfSections = getNumberOfSections(); + var validSubprogram = _patternType != SUB_CYCLE; + + var masterPosition = new Array(); + masterPosition[0] = getFramePosition(_section.getInitialPosition()); + masterPosition[1] = getFramePosition(_section.getFinalPosition()); + var tempBox = _section.getBoundingBox(); + var masterBox = new Array(); + masterBox[0] = getFramePosition(tempBox[0]); + masterBox[1] = getFramePosition(tempBox[1]); + + var rotation = getRotation(); + var translation = getTranslation(); + incrementalSubprogram = undefined; + + for (var i = 0; i < numberOfSections; ++i) { + var section = getSection(i); + if (section.getId() != sectionId) { + defineWorkPlane(section, false); + // check for valid pattern + if (_patternType == SUB_PATTERN) { + if (section.getPatternId() == _patternId) { + var patternPosition = new Array(); + patternPosition[0] = getFramePosition(section.getInitialPosition()); + patternPosition[1] = getFramePosition(section.getFinalPosition()); + tempBox = section.getBoundingBox(); + var patternBox = new Array(); + patternBox[0] = getFramePosition(tempBox[0]); + patternBox[1] = getFramePosition(tempBox[1]); + + if (areSpatialBoxesSame(masterPosition, patternPosition) && areSpatialBoxesSame(masterBox, patternBox) && !section.isMultiAxis()) { + incrementalSubprogram = incrementalSubprogram ? incrementalSubprogram : false; + } else if (!areSpatialBoxesTranslated(masterPosition, patternPosition) || !areSpatialBoxesTranslated(masterBox, patternBox)) { + validSubprogram = false; + break; + } else { + incrementalSubprogram = true; + } + } + + // check for valid cycle operation + } else if (_patternType == SUB_CYCLE) { + if ((section.getNumberOfCyclePoints() == _patternId) && (section.getNumberOfCycles() == 1)) { + var patternInitial = getFramePosition(section.getInitialPosition()); + var patternFinal = getFramePosition(section.getFinalPosition()); + if (!areSpatialVectorsDifferent(patternInitial, masterPosition[0]) && !areSpatialVectorsDifferent(patternFinal, masterPosition[1])) { + validSubprogram = true; + break; + } + } + } + } + } + setRotation(rotation); + setTranslation(translation); + return (validSubprogram); +} + +function setAxisMode(_format, _output, _prefix, _value, _incr) { + var i = _output.isEnabled(); + if (_output == zOutput) { + _output = _incr ? createIncrementalVariable({onchange: function() {retracted = false;}, prefix: _prefix}, _format) : createVariable({onchange: function() {retracted = false;}, prefix: _prefix}, _format); + } else { + _output = _incr ? createIncrementalVariable({prefix: _prefix}, _format) : createVariable({prefix: _prefix}, _format); + } + _output.format(_value); + _output.format(_value); + i = i ? _output.enable() : _output.disable(); + return _output; +} + +function setIncrementalMode(xyz, abc) { + xOutput = setAxisMode(xyzFormat, xOutput, "X", xyz.x, true); + yOutput = setAxisMode(xyzFormat, yOutput, "Y", xyz.y, true); + zOutput = setAxisMode(xyzFormat, zOutput, "Z", xyz.z, true); + aOutput = setAxisMode(abcFormat, aOutput, "A", abc.x, true); + bOutput = setAxisMode(abcFormat, bOutput, "B", abc.y, true); + cOutput = setAxisMode(abcFormat, cOutput, "C", abc.z, true); + gAbsIncModal.reset(); + writeBlock(gAbsIncModal.format(91)); + incrementalMode = true; +} + +function setAbsoluteMode(xyz, abc) { + if (incrementalMode) { + xOutput = setAxisMode(xyzFormat, xOutput, "X", xyz.x, false); + yOutput = setAxisMode(xyzFormat, yOutput, "Y", xyz.y, false); + zOutput = setAxisMode(xyzFormat, zOutput, "Z", xyz.z, false); + aOutput = setAxisMode(abcFormat, aOutput, "A", abc.x, false); + bOutput = setAxisMode(abcFormat, bOutput, "B", abc.y, false); + cOutput = setAxisMode(abcFormat, cOutput, "C", abc.z, false); + gAbsIncModal.reset(); + writeBlock(gAbsIncModal.format(90)); + incrementalMode = false; + } +} + +function onSection() { + var forceToolAndRetract = optionalSection && !currentSection.isOptional(); + optionalSection = currentSection.isOptional(); + + var insertToolCall = isFirstSection() || + currentSection.getForceToolChange && currentSection.getForceToolChange() || + (tool.number != getPreviousSection().getTool().number); + + retracted = false; + + var zIsOutput = false; // true if the Z-position has been output, used for patterns + var newWorkOffset = isFirstSection() || + (getPreviousSection().workOffset != currentSection.workOffset); // work offset changes + var newWorkPlane = isFirstSection() || + !isSameDirection(getPreviousSection().getGlobalFinalToolAxis(), currentSection.getGlobalInitialToolAxis()) || + (currentSection.isOptimizedForMachine() && getPreviousSection().isOptimizedForMachine() && + Vector.diff(getPreviousSection().getFinalToolAxisABC(), currentSection.getInitialToolAxisABC()).length > 1e-4) || + (!machineConfiguration.isMultiAxisConfiguration() && currentSection.isMultiAxis()) || + (!getPreviousSection().isMultiAxis() && currentSection.isMultiAxis() || + getPreviousSection().isMultiAxis() && !currentSection.isMultiAxis()); // force newWorkPlane between indexing and simultaneous operations + + operationNeedsSafeStart = getProperty("safeStartAllOperations") && !isFirstSection(); + + if (insertToolCall || operationNeedsSafeStart) { + if (getProperty("fastToolChange") && !isProbeOperation()) { + currentCoolantMode = COOLANT_OFF; + } else if (insertToolCall) { // no coolant off command if safe start operation + onCommand(COMMAND_COOLANT_OFF); + } + } + + if ((insertToolCall && !getProperty("fastToolChange")) || newWorkOffset || newWorkPlane || toolChecked) { + + // stop spindle before retract during tool change + if (insertToolCall && !isFirstSection() && !toolChecked && !getProperty("fastToolChange")) { + onCommand(COMMAND_STOP_SPINDLE); + } + + // retract to safe plane + writeRetract(Z); + + if (forceResetWorkPlane && newWorkPlane) { + forceWorkPlane(); + setWorkPlane(new Vector(0, 0, 0)); // reset working plane + } + } + + if (hasParameter("operation-comment")) { + var comment = getParameter("operation-comment"); + if (comment && ((comment !== lastOperationComment) || !patternIsActive || insertToolCall)) { + writeln(""); + writeComment(comment); + lastOperationComment = comment; + } else if (!patternIsActive || insertToolCall) { + writeln(""); + } + } else { + writeln(""); + } + + if (getProperty("showNotes") && hasParameter("notes")) { + var notes = getParameter("notes"); + if (notes) { + var lines = String(notes).split("\n"); + var r1 = new RegExp("^[\\s]+", "g"); + var r2 = new RegExp("[\\s]+$", "g"); + for (line in lines) { + var comment = lines[line].replace(r1, "").replace(r2, ""); + if (comment) { + writeComment(comment); + } + } + } + } + + // enable polar interpolation + if (usePolarMode && (tool.type != TOOL_PROBE)) { + if (polarDirection == undefined) { + error(localize("Polar direction property must be a vector - x,y,z.")); + return; + } + setPolarMode(currentSection, true); + } + + defineWorkPlane(currentSection, false); + var initialPosition = getFramePosition(currentSection.getInitialPosition()); + forceAny(); + + if (operationNeedsSafeStart) { + if (!retracted) { + skipBlock = true; + writeRetract(Z); + } + } + + if (insertToolCall || operationNeedsSafeStart) { + + if (getProperty("useM130ToolImages")) { + writeBlock(mFormat.format(130), "(tool" + tool.number + ".png)"); + } + + if (!isFirstSection() && getProperty("optionalStop") && insertToolCall) { + onCommand(COMMAND_OPTIONAL_STOP); + } + + if ((tool.number > 200 && tool.number < 1000) || tool.number > 9999) { + warning(localize("Tool number out of range.")); + } + + skipBlock = !insertToolCall; + writeToolBlock( + "T" + toolFormat.format(tool.number), + mFormat.format(6) + ); + if (tool.comment) { + writeComment(tool.comment); + } + if (measureTool) { + writeToolMeasureBlock(tool, false); + } + if (insertToolCall) { + forceWorkPlane(); + } + var showToolZMin = false; + if (showToolZMin) { + if (is3D()) { + var numberOfSections = getNumberOfSections(); + var zRange = currentSection.getGlobalZRange(); + var number = tool.number; + for (var i = currentSection.getId() + 1; i < numberOfSections; ++i) { + var section = getSection(i); + if (section.getTool().number != number) { + break; + } + zRange.expandToRange(section.getGlobalZRange()); + } + writeComment(localize("ZMIN") + "=" + xyzFormat.format(zRange.getMinimum())); + } + } + } + + // activate those two coolant modes before the spindle is turned on + if ((tool.coolant == COOLANT_THROUGH_TOOL) || (tool.coolant == COOLANT_AIR_THROUGH_TOOL) || (tool.coolant == COOLANT_FLOOD_THROUGH_TOOL)) { + if (!isFirstSection() && !insertToolCall && (currentCoolantMode != tool.coolant)) { + onCommand(COMMAND_STOP_SPINDLE); + forceSpindleSpeed = true; + } + setCoolant(tool.coolant); + } else if ((currentCoolantMode == COOLANT_THROUGH_TOOL) || (currentCoolantMode == COOLANT_AIR_THROUGH_TOOL) || (currentCoolantMode == COOLANT_FLOOD_THROUGH_TOOL)) { + onCommand(COMMAND_STOP_SPINDLE); + setCoolant(COOLANT_OFF); + forceSpindleSpeed = true; + } + + if (toolChecked) { + forceSpindleSpeed = true; // spindle must be restarted if tool is checked without a tool change + toolChecked = false; // state of tool is not known at the beginning of a section since it could be broken for the previous section + } + var spindleChanged = tool.type != TOOL_PROBE && + (insertToolCall || forceSpindleSpeed || isFirstSection() || + (rpmFormat.areDifferent(spindleSpeed, sOutput.getCurrent())) || + (tool.clockwise != getPreviousSection().getTool().clockwise)); + if (spindleChanged || (operationNeedsSafeStart && tool.type != TOOL_PROBE)) { + forceSpindleSpeed = false; + + if (spindleSpeed < 1) { + error(localize("Spindle speed out of range.")); + return; + } + maximumSpindleRPM = machineConfiguration.getMaximumSpindleSpeed() > 0 ? machineConfiguration.getMaximumSpindleSpeed() : maximumSpindleRPM; + if (spindleSpeed > maximumSpindleRPM) { + warning(subst(localize("Spindle speed '" + spindleSpeed + " RPM' exceeds maximum value of '%1 RPM."), maximumSpindleRPM)); + } + skipBlock = !spindleChanged; + writeBlock( + sOutput.format(spindleSpeed), mFormat.format(tool.clockwise ? 3 : 4) + ); + } + + previewImage(); + + if (getProperty("useParametricFeed") && + hasParameter("operation-strategy") && + (getParameter("operation-strategy") != "drill") && // legacy + !(currentSection.hasAnyCycle && currentSection.hasAnyCycle())) { + if (!insertToolCall && + activeMovements && + (getCurrentSectionId() > 0) && + ((getPreviousSection().getPatternId() == currentSection.getPatternId()) && (currentSection.getPatternId() != 0))) { + // use the current feeds + } else { + initializeActiveFeeds(); + } + } else { + activeMovements = undefined; + } + + // wcs + if (insertToolCall || operationNeedsSafeStart) { // force work offset when changing tool + currentWorkOffset = undefined; + skipBlock = operationNeedsSafeStart && !newWorkOffset && !insertToolCall; + } + var workOffset = currentSection.workOffset; + if (workOffset == 0) { + warningOnce(localize("Work offset has not been specified. Using G54 as WCS."), WARNING_WORK_OFFSET); + workOffset = 1; + } + if (workOffset > 0) { + if (workOffset > 6) { + var code = workOffset - 6; + if (code > 99) { + error(localize("Work offset out of range.")); + return; + } + if (workOffset != currentWorkOffset) { + if (!skipBlock) { + forceWorkPlane(); + } + writeBlock(gFormat.format(154), "P" + code); + currentWorkOffset = workOffset; + } + } else { + if (workOffset != currentWorkOffset) { + if (!skipBlock) { + forceWorkPlane(); + } + writeBlock(gFormat.format(53 + workOffset)); // G54->G59 + currentWorkOffset = workOffset; + } + } + } + + if (newWorkPlane || (insertToolCall && !retracted)) { // go to home position for safety + if (!retracted) { + writeRetract(Z); + } + if (getProperty("forceHomeOnIndexing") && machineConfiguration.isMultiAxisConfiguration()) { + writeRetract(X, Y); + } + } + + // Unwind axis if previous section was Multi-Axis + if (!isFirstSection() && (getPreviousSection().isMultiAxis() || usePolarMode) && machineConfiguration.isMachineCoordinate(2)) { // TAG + if (!retracted) { + moveToSafeRetractPosition(); + } + writeBlock(gFormat.format(28), gAbsIncModal.format(91), "C" + abcFormat.format(0)); + writeBlock(gAbsIncModal.format(90)); + currentMachineABC.setZ(0); + } + + if (newWorkOffset) { + forceWorkPlane(); + } + + var abc = defineWorkPlane(currentSection, true); + + setProbeAngle(); // output probe angle rotations if required + + gMotionModal.reset(); + + if (getProperty("useG187")) { + writeG187(); + } + + var G = ((highFeedMapping != HIGH_FEED_NO_MAPPING) || !getProperty("useG0")) ? 1 : 0; + var F = ((highFeedMapping != HIGH_FEED_NO_MAPPING) || !getProperty("useG0")) ? getFeed(toPreciseUnit(highFeedrate, MM)) : ""; + if (insertToolCall || retracted || operationNeedsSafeStart || !lengthCompensationActive || + (!isFirstSection() && (currentSection.isMultiAxis() != getPreviousSection().isMultiAxis()))) { + var _skipBlock = !(insertToolCall || retracted || + (!isFirstSection() && (currentSection.isMultiAxis() != getPreviousSection().isMultiAxis()))); + var lengthOffset = tool.lengthOffset; + if ((lengthOffset > 200 && lengthOffset < 1000) || lengthOffset > 9999) { + error(localize("Length offset out of range.")); + return; + } + + gMotionModal.reset(); + writeBlock(gPlaneModal.format(17)); + + if (usePolarMode) { + if (!retracted) { + skipBlock = _skipBlock; + moveToSafeRetractPosition(); + } + var polarPosition = getPolarPosition(initialPosition.x, initialPosition.y, initialPosition.z); + setCurrentPositionAndDirection(polarPosition); + initialPosition = new Vector(polarPosition.first.x, polarPosition.first.y, polarPosition.first.z); + writeBlock(gMotionModal.format(0), aOutput.format(polarPosition.second.x), bOutput.format(polarPosition.second.y), cOutput.format(polarPosition.second.z)); + } + + if (!machineConfiguration.isHeadConfiguration()) { + if (tcpIsSupported && useDwoForPositioning && currentSection.isMultiAxis()) { + var O = machineConfiguration.getOrientation(abc); + var initialPositionDWO = O.getTransposed().multiply(getGlobalPosition(currentSection.getInitialPosition())); + // writeComment("PREPOSITIONING START"); + skipBlock = _skipBlock; + writeBlock(gFormat.format(254)); + skipBlock = _skipBlock; + writeBlock(gAbsIncModal.format(90), gMotionModal.format(G), xOutput.format(initialPositionDWO.x), yOutput.format(initialPositionDWO.y), F); + skipBlock = _skipBlock; + writeBlock(gFormat.format(255)); + // writeComment("PREPOSITIONING END"); + skipBlock = _skipBlock; + writeBlock( + gMotionModal.format(G), + conditional(!currentSection.isMultiAxis() || !tcpIsSupported, gFormat.format(43)), + conditional(currentSection.isMultiAxis() && tcpIsSupported, gFormat.format(234)), + xOutput.format(initialPosition.x), yOutput.format(initialPosition.y), zOutput.format(initialPosition.z), F, + hFormat.format(lengthOffset) + ); + } else { + skipBlock = _skipBlock; + writeBlock(gAbsIncModal.format(90), gMotionModal.format(G), xOutput.format(initialPosition.x), yOutput.format(initialPosition.y), F); + skipBlock = _skipBlock; + writeBlock( + gMotionModal.format(0), + conditional(!currentSection.isMultiAxis() || !tcpIsSupported, gFormat.format(43)), + conditional(currentSection.isMultiAxis() && tcpIsSupported, gFormat.format(234)), + zOutput.format(initialPosition.z), + hFormat.format(lengthOffset) + ); + } + } else { + skipBlock = _skipBlock; + writeBlock( + gAbsIncModal.format(90), + gMotionModal.format(G), + conditional(!currentSection.isMultiAxis() || !tcpIsSupported, gFormat.format(43)), + conditional(currentSection.isMultiAxis() && tcpIsSupported, gFormat.format(234)), + xOutput.format(initialPosition.x), + yOutput.format(initialPosition.y), + zOutput.format(initialPosition.z), + F, + hFormat.format(lengthOffset) + ); + } + zIsOutput = true; + lengthCompensationActive = true; + if (_skipBlock) { + forceXYZ(); + var x = xOutput.format(initialPosition.x); + var y = yOutput.format(initialPosition.y); + if (x && y) { + // axes are not synchronized + writeBlock(gAbsIncModal.format(90), gMotionModal.format(G), x, y, F); + } else { + writeBlock(gAbsIncModal.format(90), gMotionModal.format(0), x, y); + } + } + + gMotionModal.reset(); + } else { + validate(lengthCompensationActive, "Length compensation is not active."); + if (getCurrentPosition().z < initialPosition.z) { + writeBlock(gMotionModal.format(0), zOutput.format(initialPosition.z)); + zIsOutput = true; + } + var x = xOutput.format(initialPosition.x); + var y = yOutput.format(initialPosition.y); + if (x && y) { + // axes are not synchronized + writeBlock(gAbsIncModal.format(90), gMotionModal.format(G), x, y, F); + } else { + writeBlock(gAbsIncModal.format(90), gMotionModal.format(0), x, y); + } + } + + validate(lengthCompensationActive, "Length compensation is not active."); + + if (insertToolCall || operationNeedsSafeStart) { + if (getProperty("preloadTool")) { + var nextTool = getNextTool(tool.number); + if (nextTool) { + skipBlock = !insertToolCall; + writeBlock("T" + toolFormat.format(nextTool.number)); + } else { + // preload first tool + var section = getSection(0); + var firstToolNumber = section.getTool().number; + if (tool.number != firstToolNumber) { + skipBlock = !insertToolCall; + writeBlock("T" + toolFormat.format(firstToolNumber)); + } + } + } + } + + 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 + inspectionCreateResultsFileHeader(); + } else { + // surface Inspection + if (isInspectionOperation() && (typeof inspectionProcessSectionStart == "function")) { + inspectionProcessSectionStart(); + } + } + + var inMapping = takeInput("Y/N?", ['Y', 'N', 'X', 'Y', 'Z']); + writeln(inMapping) + + // Modified 06/09/21 | Gavin Williams | will1742 + // Issue 000 Init coolant after positioning + setCoolant(tool.coolant); + + // define subprogram + subprogramDefine(initialPosition, abc, retracted, zIsOutput); +} + +// Added 6/14/21 | Gavin Williams | will1742 +// Takes input from the user +// Input: string prompt, will be displayed to users +// char array options, capital letters accepted as input +// Output: 2D array [Letter, Coorresponding GOTO] +// EX: [Y, 56][N, 57] +var macroNumber = 500; +function takeInput(prompt, options) { + + // Cycle through macro variables, reset at end of general purpose vars + if (macroNumber > 549) macroNumber = 500; + + // init var to 0 + writeln("#" + macroNumber + "=0"); + + // disply prompt and save response + writeln("N" + sequenceNumber + " M109 " + "P" + macroNumber + " (" + prompt + ")"); + var gotoRef = sequenceNumber; + + // wait for input + writeln("IF[#" + macroNumber + " EQ 0.] GOTO" + gotoRef) + + // TODO: Line number and GOTO optimization + // print if's and goto's + var gotoMap =[]; + var gotoInc = 1; + options.forEach(function (element) { + writeln("IF[#" + macroNumber + " EQ " + element.charCodeAt(0) + ".] GOTO" + (sequenceNumber + gotoInc) + " (" + element + ")"); + gotoMap.push([element, (sequenceNumber + gotoInc)]); + gotoInc += 1; + }); + + for (i = 5; i < gotoInc; i+=5) { + sequenceNumber += getProperty("sequenceNumberIncrement"); + } + + // return to input until valid option is entered + writeln("GOTO" + gotoRef) + + // increase var number, iterate sequence number + macroNumber += 1; + sequenceNumber += getProperty("sequenceNumberIncrement"); + return gotoMap; +} + +function onDwell(seconds) { + if (seconds > 99999.999) { + warning(localize("Dwelling time is out of range.")); + } + seconds = clamp(0.001, seconds, 99999.999); + writeBlock(gFeedModeModal.format(94), gFormat.format(4), "P" + milliFormat.format(seconds * 1000)); +} + +function onSpindleSpeed(spindleSpeed) { + writeBlock(sOutput.format(spindleSpeed)); +} + +function onCycle() { + writeBlock(gPlaneModal.format(17)); +} + +function getCommonCycle(x, y, z, r, c) { + forceXYZ(); + if (usePolarMode) { + var polarPosition = getPolarPosition(x, y, z); + return [xOutput.format(polarPosition.first.x), yOutput.format(polarPosition.first.y), + zOutput.format(polarPosition.first.z), + aOutput.format(polarPosition.second.x), + bOutput.format(polarPosition.second.y), + cOutput.format(polarPosition.second.z), + "R" + xyzFormat.format(r)]; + } else { + if (incrementalMode) { + zOutput.format(c); + return [xOutput.format(x), yOutput.format(y), + "Z" + xyzFormat.format(z - r), + "R" + xyzFormat.format(r - c)]; + } else { + return [xOutput.format(x), yOutput.format(y), + zOutput.format(z), + "R" + xyzFormat.format(r)]; + } + } +} + +function setCyclePosition(_position) { + switch (gPlaneModal.getCurrent()) { + case 17: // XY + zOutput.format(_position); + break; + case 18: // ZX + yOutput.format(_position); + break; + case 19: // YZ + xOutput.format(_position); + break; + } +} + +/** Convert approach to sign. */ +function approach(value) { + validate((value == "positive") || (value == "negative"), "Invalid approach."); + return (value == "positive") ? 1 : -1; +} + +function setProbeAngleMethod() { + probeVariables.probeAngleMethod = (machineConfiguration.getNumberOfAxes() < 5 || is3D()) ? (getProperty("useG54x4") ? "G54.4" : "G68") : "UNSUPPORTED"; + 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()) { + probeVariables.probeAngleMethod = "AXIS_ROT"; + probeVariables.rotationalAxis = axes[i].getCoordinate(); + break; + } + } + probeVariables.outputRotationCodes = true; +} + +/** Output rotation offset based on angular probing cycle. */ +function setProbeAngle() { + if (probeVariables.outputRotationCodes) { + 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 = 26000 + (probeOutputWorkOffset * 10); + writeBlock("#" + param + "=#135"); + writeBlock("#" + (param + 1) + "=#136"); + writeBlock("#" + (param + 5) + "=#144"); + writeBlock(gFormat.format(54.4), "P" + probeOutputWorkOffset); + break; + case "G68": + gRotationModal.reset(); + gAbsIncModal.reset(); + writeBlock(gRotationModal.format(68), gAbsIncModal.format(90), probeVariables.compensationXY, "R[#194]"); + validateWorkOffset = true; + break; + case "AXIS_ROT": + var param = 5200 + probeOutputWorkOffset * 20 + probeVariables.rotationalAxis + 4; + writeBlock("#" + param + " = " + "[#" + param + " + #194]"); + 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 protectedProbeMove(_cycle, x, y, z) { + var _x = xOutput.format(x); + var _y = yOutput.format(y); + var _z = zOutput.format(z); + if (_z && z >= getCurrentPosition().z) { + writeBlock(gFormat.format(65), "P" + 9810, _z, getFeed(cycle.feedrate)); // protected positioning move + } + if (_x || _y) { + writeBlock(gFormat.format(65), "P" + 9810, _x, _y, getFeed(toPreciseUnit(highFeedrate, MM))); // protected positioning move + } + if (_z && z < getCurrentPosition().z) { + writeBlock(gFormat.format(65), "P" + 9810, _z, getFeed(cycle.feedrate)); // protected positioning move + } +} + +function cancelG68Rotation(force) { + if (force) { + gRotationModal.reset(); + } + writeBlock(gRotationModal.format(69)); +} + +function onCyclePoint(x, y, z) { + if (isInspectionOperation() && (typeof inspectionCycleInspect == "function")) { + inspectionCycleInspect(cycle, x, y, z); + return; + } + if (!isSameDirection(getRotation().forward, new Vector(0, 0, 1))) { + expandCyclePoint(x, y, z); + return; + } + if (isProbeOperation()) { + if (!isSameDirection(currentSection.workPlane.forward, new Vector(0, 0, 1))) { + if (!allowIndexingWCSProbing && currentSection.strategy == "probe") { + error(localize("Updating WCS / work offset using probing is only supported by the CNC in the WCS frame.")); + return; + } else if (getProperty("useDWO")) { + error(localize("Your machine does not support the selected probing operation with DWO enabled.")); + 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 forceCycle = false; + switch (cycleType) { + case "tapping-with-chip-breaking": + case "left-tapping-with-chip-breaking": + case "right-tapping-with-chip-breaking": + forceCycle = true; + if (!isFirstCyclePoint()) { + writeBlock(gCycleModal.format(80)); + gMotionModal.reset(); + } + } + if (forceCycle || isFirstCyclePoint() || isProbeOperation()) { + if (!isProbeOperation()) { + // return to initial Z which is clearance plane and set absolute mode + repositionToCycleClearance(cycle, x, y, z); + } + + var F = cycle.feedrate; + var P = !cycle.dwell ? 0 : clamp(1, cycle.dwell * 1000, 99999999); // in milliseconds + + switch (cycleType) { + case "drilling": + writeBlock( + gRetractModal.format(98), gCycleModal.format(81), + getCommonCycle(x, y, z, cycle.retract, cycle.clearance), + conditional(cycleReverse, "E2000"), feedOutput.format(F) + ); + break; + case "counter-boring": + if (P > 0) { + writeBlock( + gRetractModal.format(98), gCycleModal.format(82), + getCommonCycle(x, y, z, cycle.retract, cycle.clearance), + "P" + milliFormat.format(P), // not optional + conditional(cycleReverse, "E2000"), feedOutput.format(F) + ); + } else { + writeBlock( + gRetractModal.format(98), gCycleModal.format(81), + getCommonCycle(x, y, z, cycle.retract, cycle.clearance), + conditional(cycleReverse, "E2000"), feedOutput.format(F) + ); + } + break; + case "chip-breaking": + if ((cycle.accumulatedDepth < cycle.depth) && (cycle.incrementalDepthReduction > 0)) { + expandCyclePoint(x, y, z); + } else if (cycle.accumulatedDepth < cycle.depth) { + writeBlock( + gRetractModal.format(98), gCycleModal.format(73), + getCommonCycle(x, y, z, cycle.retract, cycle.clearance), + ("Q" + xyzFormat.format(cycle.incrementalDepth)), + ("K" + xyzFormat.format(cycle.accumulatedDepth)), + conditional(P > 0, "P" + milliFormat.format(P)), // optional + conditional(cycleReverse, "E2000"), feedOutput.format(F) + ); + } else { + writeBlock( + gRetractModal.format(98), gCycleModal.format(73), + getCommonCycle(x, y, z, cycle.retract, cycle.clearance), + (((cycle.incrementalDepthReduction > 0) ? "I" : "Q") + xyzFormat.format(cycle.incrementalDepth)), + conditional(cycle.incrementalDepthReduction > 0, "J" + xyzFormat.format(cycle.incrementalDepthReduction)), + conditional(cycle.incrementalDepthReduction > 0, "K" + xyzFormat.format(cycle.minimumIncrementalDepth)), + conditional(P > 0, "P" + milliFormat.format(P)), // optional + conditional(cycleReverse, "E2000"), feedOutput.format(F) + ); + } + break; + case "deep-drilling": + writeBlock( + gRetractModal.format(98), gCycleModal.format(83), + getCommonCycle(x, y, z, cycle.retract, cycle.clearance), + (((cycle.incrementalDepthReduction > 0) ? "I" : "Q") + xyzFormat.format(cycle.incrementalDepth)), + conditional(cycle.incrementalDepthReduction > 0, "J" + xyzFormat.format(cycle.incrementalDepthReduction)), + conditional(cycle.incrementalDepthReduction > 0, "K" + xyzFormat.format(cycle.minimumIncrementalDepth)), + conditional(P > 0, "P" + milliFormat.format(P)), // optional + conditional(cycleReverse, "E2000"), feedOutput.format(F) + ); + break; + case "tapping": + var tappingFPM = tool.getThreadPitch() * rpmFormat.getResultingValue(spindleSpeed); + F = (getProperty("useG95forTapping") ? tool.getThreadPitch() : tappingFPM); + if (getProperty("useG95forTapping")) { + writeBlock(gFeedModeModal.format(95)); + } + writeBlock( + gRetractModal.format(98), gCycleModal.format((tool.type == TOOL_TAP_LEFT_HAND) ? 74 : 84), + getCommonCycle(x, y, z, cycle.retract, cycle.clearance), + conditional(cycleReverse, "E2000"), pitchOutput.format(F) + ); + forceFeed(); + break; + case "left-tapping": + var tappingFPM = tool.getThreadPitch() * rpmFormat.getResultingValue(spindleSpeed); + F = (getProperty("useG95forTapping") ? tool.getThreadPitch() : tappingFPM); + if (getProperty("useG95forTapping")) { + writeBlock(gFeedModeModal.format(95)); + } + writeBlock( + gRetractModal.format(98), gCycleModal.format(74), + getCommonCycle(x, y, z, cycle.retract, cycle.clearance), + conditional(cycleReverse, "E2000"), pitchOutput.format(F) + ); + forceFeed(); + break; + case "right-tapping": + var tappingFPM = tool.getThreadPitch() * rpmFormat.getResultingValue(spindleSpeed); + F = (getProperty("useG95forTapping") ? tool.getThreadPitch() : tappingFPM); + if (getProperty("useG95forTapping")) { + writeBlock(gFeedModeModal.format(95)); + } + writeBlock( + gRetractModal.format(98), gCycleModal.format(84), + getCommonCycle(x, y, z, cycle.retract, cycle.clearance), + conditional(cycleReverse, "E2000"), pitchOutput.format(F) + ); + forceFeed(); + break; + case "tapping-with-chip-breaking": + case "left-tapping-with-chip-breaking": + case "right-tapping-with-chip-breaking": + var tappingFPM = tool.getThreadPitch() * rpmFormat.getResultingValue(spindleSpeed); + F = (getProperty("useG95forTapping") ? tool.getThreadPitch() : tappingFPM); + if (getProperty("useG95forTapping")) { + writeBlock(gFeedModeModal.format(95)); + } + // Parameter 57 bit 6, REPT RIG TAP, is set to 1 (On) + // On Mill software versions12.09 and above, REPT RIG TAP has been moved from the Parameters to Setting 133 + var u = cycle.stock; + var step = cycle.incrementalDepth; + var first = true; + while (u > cycle.bottom) { + if (step < cycle.minimumIncrementalDepth) { + step = cycle.minimumIncrementalDepth; + } + + u -= step; + step -= cycle.incrementalDepthReduction; + gCycleModal.reset(); // required + if ((u - 0.001) <= cycle.bottom) { + u = cycle.bottom; + } + if (first) { + first = false; + writeBlock( + gRetractModal.format(99), gCycleModal.format((tool.type == TOOL_TAP_LEFT_HAND ? 74 : 84)), + getCommonCycle((gPlaneModal.getCurrent() == 19) ? u : x, (gPlaneModal.getCurrent() == 18) ? u : y, (gPlaneModal.getCurrent() == 17) ? u : z, cycle.retract, cycle.clearance), + conditional(cycleReverse, "E2000"), pitchOutput.format(F) + ); + } else { + var position; + var depth; + switch (gPlaneModal.getCurrent()) { + case 17: + xOutput.reset(); + position = xOutput.format(x); + depth = "Z" + xyzFormat.format(u); + break; + case 18: + zOutput.reset(); + position = zOutput.format(z); + depth = "Y" + xyzFormat.format(u); + break; + case 19: + yOutput.reset(); + position = yOutput.format(y); + depth = "X" + xyzFormat.format(u); + break; + } + writeBlock(conditional(u <= cycle.bottom, gRetractModal.format(98)), position, depth); + } + } + forceFeed(); + break; + case "fine-boring": + writeBlock( + gRetractModal.format(98), gCycleModal.format(76), + getCommonCycle(x, y, z, cycle.retract, cycle.clearance), + "P" + milliFormat.format(P), // not optional + "Q" + xyzFormat.format(cycle.shift), + conditional(cycleReverse, "E2000"), feedOutput.format(F) + ); + forceSpindleSpeed = true; + break; + case "back-boring": + if (P > 0) { + expandCyclePoint(x, y, z); + } else { + 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), gCycleModal.format(77), + getCommonCycle(x - dx, y - dy, z - dz, cycle.bottom, cycle.clearance), + "Q" + xyzFormat.format(cycle.shift), + conditional(cycleReverse, "E2000"), feedOutput.format(F) + ); + forceSpindleSpeed = true; + } + break; + case "reaming": + writeBlock( + gRetractModal.format(98), gCycleModal.format(85), + getCommonCycle(x, y, z, cycle.retract, cycle.clearance), + conditional(cycleReverse, "E2000"), feedOutput.format(F) + ); + break; + case "stop-boring": + if (P > 0) { + expandCyclePoint(x, y, z); + } else { + writeBlock( + gRetractModal.format(98), gCycleModal.format(86), + getCommonCycle(x, y, z, cycle.retract, cycle.clearance), + conditional(cycleReverse, "E2000"), feedOutput.format(F) + ); + forceSpindleSpeed = true; + } + break; + case "manual-boring": + writeBlock( + gRetractModal.format(98), gCycleModal.format(88), + getCommonCycle(x, y, z, cycle.retract, cycle.clearance), + "P" + milliFormat.format(P), // not optional + conditional(cycleReverse, "E2000"), feedOutput.format(F) + ); + break; + case "boring": + writeBlock( + gRetractModal.format(98), gCycleModal.format(89), + getCommonCycle(x, y, z, cycle.retract, cycle.clearance), + "P" + milliFormat.format(P), // not optional + conditional(cycleReverse, "E2000"), feedOutput.format(F) + ); + break; + + case "probing-x": + protectedProbeMove(cycle, x, y, z - cycle.depth); + writeBlock( + gFormat.format(65), "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( + gFormat.format(65), "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( + gFormat.format(65), "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( + gFormat.format(65), "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( + gFormat.format(65), "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( + gFormat.format(65), "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( + gFormat.format(65), "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( + gFormat.format(65), "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( + gFormat.format(65), "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( + gFormat.format(65), "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( + gFormat.format(65), "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( + gFormat.format(65), "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( + gFormat.format(65), "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( + gFormat.format(65), "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( + gFormat.format(65), "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( + gFormat.format(65), "P" + 9812, + "X" + xyzFormat.format(cycle.width1), + "Q" + xyzFormat.format(cycle.probeOvertravel), + // not required "R" + xyzFormat.format(-cycle.probeClearance), + getProbingArguments(cycle, true) + ); + writeBlock( + gFormat.format(65), "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( + gFormat.format(65), "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) + ); + writeBlock( + gFormat.format(65), "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( + gFormat.format(65), "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) + ); + writeBlock( + gFormat.format(65), "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(); + probeVariables.compensationXY = "X[#185] Y[#186]"; + } + } + protectedProbeMove(cycle, x, y, z - cycle.depth); + writeBlock( + gFormat.format(65), "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(); + probeVariables.compensationXY = "X[#185] Y[#186]"; + } + } + protectedProbeMove(cycle, x, y, z - cycle.depth); + writeBlock( + gFormat.format(65), "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( + gFormat.format(65), "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( + gFormat.format(65), "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( + gFormat.format(65), "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( + gFormat.format(65), "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; + default: + expandCyclePoint(x, y, z); + } + + // place cycle operation in subprogram + if (cycleSubprogramIsActive) { + if (forceCycle || cycleExpanded || isProbeOperation()) { + cycleSubprogramIsActive = false; + } else { + // call subprogram + writeBlock(mFormat.format(97), "P" + nFormat.format(currentSubprogram)); + subprogramStart(new Vector(x, y, z), new Vector(0, 0, 0), false); + } + } + if (incrementalMode) { // set current position to clearance height + setCyclePosition(cycle.clearance); + } + + // 2nd through nth cycle point + } else { + if (cycleExpanded) { + expandCyclePoint(x, y, z); + } else { + if (usePolarMode) { + var polarPosition = getPolarPosition(x, y, z); + writeBlock(xOutput.format(polarPosition.first.x), yOutput.format(polarPosition.first.y), zOutput.format(polarPosition.first.z), + aOutput.format(polarPosition.second.x), bOutput.format(polarPosition.second.y), cOutput.format(polarPosition.second.z)); + return; + } + var _x; + var _y; + var _z; + if (!xyzFormat.areDifferent(x, xOutput.getCurrent()) && + !xyzFormat.areDifferent(y, yOutput.getCurrent()) && + !xyzFormat.areDifferent(z, zOutput.getCurrent())) { + switch (gPlaneModal.getCurrent()) { + case 17: // XY + xOutput.reset(); // at least one axis is required + break; + case 18: // ZX + zOutput.reset(); // at least one axis is required + break; + case 19: // YZ + yOutput.reset(); // at least one axis is required + break; + } + } + if (incrementalMode) { // set current position to retract height + setCyclePosition(cycle.retract); + } + writeBlock(xOutput.format(x), yOutput.format(y), zOutput.format(z)); + if (incrementalMode) { // set current position to clearance height + setCyclePosition(cycle.clearance); + } + } + } +} + +function getProbingArguments(cycle, updateWCS) { + var outputWCSCode = updateWCS && currentSection.strategy == "probe"; + if (outputWCSCode) { + validate(probeOutputWorkOffset <= 99, "Work offset is out of range."); + var nextWorkOffset = hasNextSection() ? getNextSection().workOffset == 0 ? 1 : getNextSection().workOffset : -1; + if (probeOutputWorkOffset == 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, "S" + probeWCSFormat.format(probeOutputWorkOffset > 6 ? (0.01 * (probeOutputWorkOffset - 6) + 154) : probeOutputWorkOffset)) + ]; +} + +function onCycleEnd() { + if (isProbeOperation()) { + zOutput.reset(); + gMotionModal.reset(); + writeBlock(gFormat.format(65), "P" + 9810, zOutput.format(cycle.retract)); // protected retract move + } else { + if (cycleSubprogramIsActive) { + subprogramEnd(); + cycleSubprogramIsActive = false; + } + if (!cycleExpanded) { + writeBlock(gCycleModal.format(80), conditional(getProperty("useG95forTapping"), gFeedModeModal.format(94))); + gMotionModal.reset(); + } + } +} + +var pendingRadiusCompensation = -1; + +function onRadiusCompensation() { + pendingRadiusCompensation = radiusCompensation; +} + +var forceG0 = false; +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; + } + if (!getProperty("useG0") && !forceG0 && (((x ? 1 : 0) + (y ? 1 : 0) + (z ? 1 : 0)) > 1)) { + // axes are not synchronized + writeBlock(gFeedModeModal.format(94), gMotionModal.format(1), x, y, z, getFeed(toPreciseUnit(highFeedrate, MM))); + } else { + writeBlock(gMotionModal.format(0), x, y, z); + forceFeed(); + } + forceG0 = false; + } +} + +function onLinear(_x, _y, _z, feed) { + if (pendingRadiusCompensation >= 0) { + // ensure that we end at desired position when compensation is turned off + xOutput.reset(); + yOutput.reset(); + } + var x = xOutput.format(_x); + var y = yOutput.format(_y); + var z = zOutput.format(_z); + var f = getFeed(feed); + if (x || y || z) { + if (pendingRadiusCompensation >= 0) { + pendingRadiusCompensation = -1; + var d = tool.diameterOffset; + if ((d > 200 && d < 1000) || d > 9999) { + warning(localize("Diameter offset out of range.")); + } + writeBlock(gPlaneModal.format(17), gFeedModeModal.format(94)); + switch (radiusCompensation) { + case RADIUS_COMPENSATION_LEFT: + dOutput.reset(); + writeBlock(gMotionModal.format(1), gFormat.format(41), x, y, z, dOutput.format(d), f); + break; + case RADIUS_COMPENSATION_RIGHT: + dOutput.reset(); + writeBlock(gMotionModal.format(1), gFormat.format(42), x, y, z, dOutput.format(d), f); + break; + default: + writeBlock(gMotionModal.format(1), gFormat.format(40), x, y, z, f); + } + } else { + writeBlock(gFeedModeModal.format(94), gMotionModal.format(1), x, y, z, f); + } + } else if (f) { + if (getNextRecord().isMotion()) { // try not to output feed without motion + forceFeed(); // force feed on next line + } else { + writeBlock(gMotionModal.format(1), f); + } + } +} + +function onRapid5D(_x, _y, _z, _a, _b, _c) { + if (!currentSection.isOptimizedForMachine()) { + error(localize("This post configuration has not been customized for 5-axis simultaneous toolpath.")); + return; + } + if (pendingRadiusCompensation >= 0) { + error(localize("Radius compensation mode cannot be changed at rapid traversal.")); + return; + } + + var num = + (xyzFormat.areDifferent(_x, xOutput.getCurrent()) ? 1 : 0) + + (xyzFormat.areDifferent(_y, yOutput.getCurrent()) ? 1 : 0) + + (xyzFormat.areDifferent(_z, zOutput.getCurrent()) ? 1 : 0) + + ((aOutput.isEnabled() && abcFormat.areDifferent(_a, aOutput.getCurrent())) ? 1 : 0) + + ((bOutput.isEnabled() && abcFormat.areDifferent(_b, bOutput.getCurrent())) ? 1 : 0) + + ((cOutput.isEnabled() && abcFormat.areDifferent(_c, cOutput.getCurrent())) ? 1 : 0); + if (!getProperty("useG0") && !forceG0 && (tcpIsSupported || (num > 1))) { + invokeOnLinear5D(_x, _y, _z, _a, _b, _c, toPreciseUnit(highFeedrate, MM)); // onLinear5D handles inverse time feedrates + return; + } + + var x = xOutput.format(_x); + var y = yOutput.format(_y); + var z = zOutput.format(_z); + var a = aOutput.format(_a); + var b = bOutput.format(_b); + var c = cOutput.format(_c); + + if (x || y || z || a || b || c) { + writeBlock(gMotionModal.format(0), x, y, z, a, b, c); + forceFeed(); + forceG0 = false; + } +} + +function onLinear5D(_x, _y, _z, _a, _b, _c, feed, feedMode) { + if (!currentSection.isOptimizedForMachine()) { + error(localize("This post configuration has not been customized for 5-axis simultaneous toolpath.")); + return; + } + if (pendingRadiusCompensation >= 0) { + error(localize("Radius compensation cannot be activated/deactivated for 5-axis move.")); + return; + } + + var x = xOutput.format(_x); + var y = yOutput.format(_y); + var z = zOutput.format(_z); + var a = aOutput.format(_a); + var b = bOutput.format(_b); + var c = cOutput.format(_c); + + if (feedMode == FEED_INVERSE_TIME) { + forceFeed(); + } + var f = getFeed(feed); + var fMode = (feedMode == FEED_INVERSE_TIME) ? 93 : 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 moveToSafeRetractPosition(isRetracted) { + var _skipBlock = skipBlock; + if (!isRetracted) { + writeRetract(Z); + } + if (getProperty("forceHomeOnIndexing")) { + skipBlock = _skipBlock; + writeRetract(X, Y); + } +} + +// Start of onRewindMachine logic +var performRewinds = false; // only use this setting with hardcoded machine configurations, set to true to enable the rewind/reconfigure logic +var stockExpansion = new Vector(toPreciseUnit(0.1, IN), toPreciseUnit(0.1, IN), toPreciseUnit(0.1, IN)); // expand stock XYZ values +safeRetractDistance = (unit == IN) ? 1 : 25; // additional distance to retract out of stock +safeRetractFeed = (unit == IN) ? 20 : 500; // retract feed rate +safePlungeFeed = (unit == IN) ? 10 : 250; // plunge feed rate + +/** Allow user to override the onRewind logic. */ +function onRewindMachineEntry(_a, _b, _c) { + return false; +} + +/** Retract to safe position before indexing rotaries. */ +function onMoveToSafeRetractPosition() { + // cancel TCP so that tool doesn't follow rotaries + if (currentSection.isMultiAxis() && tcpIsSupported) { + disableLengthCompensation(false, "TCPC OFF"); + } + moveToSafeRetractPosition(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(); + forceG0 = true; + invokeOnRapid5D(_x, _y, _z, _a, _b, _c); + setCurrentABC(new Vector(_a, _b, _c)); + xOutput.enable(); + yOutput.enable(); + zOutput.enable(); +} + +/** Return from safe position after indexing rotaries. */ +function onReturnFromSafeRetractPosition(_x, _y, _z) { + // reinstate TCP + if (tcpIsSupported) { + writeBlock(gFormat.format(234), hFormat.format(tool.lengthOffset), formatComment("TCPC ON")); + lengthCompensationActive = true; + } + + // position in XY + forceXYZ(); + xOutput.reset(); + yOutput.reset(); + zOutput.disable(); + forceG0 = true; + invokeOnRapid(_x, _y, _z); + + // position in Z + zOutput.enable(); + invokeOnRapid(_x, _y, _z); +} +// End of onRewindMachine logic + +// Start of polar interpolation +var usePolarMode = false; // enables polar interpolation for a single operation +var polarDirection = new Vector(1, 0, 0); // vector to maintain tool at while in polar interpolation +var saveTcpIsSupported = undefined; +function setPolarMode(section, mode) { + if (!mode) { // turn off polar mode if required + if (usePolarMode) { + var currentPosition = getCurrentPosition(); + var polarPosition = getPolarPosition(currentPosition.x, currentPosition.y, currentPosition.z); + currentMachineABC = new Vector(polarPosition.second.x, polarPosition.second.y, polarPosition.second.z); + deactivatePolarMode(); + tcpIsSupported = saveTcpIsSupported; + setFeedrateMode(true); + usePolarMode = false; + } + return; + } + + var direction = polarDirection; + + // determine the rotary axis to use for polar interpolation + var axis = undefined; + if (machineConfiguration.getAxisV().isEnabled()) { + if (Vector.dot(machineConfiguration.getAxisV().getAxis(), section.workPlane.getForward()) != 0) { + axis = machineConfiguration.getAxisV(); + } + } + if (axis == undefined && machineConfiguration.getAxisU().isEnabled()) { + if (Vector.dot(machineConfiguration.getAxisU().getAxis(), section.workPlane.getForward()) != 0) { + axis = machineConfiguration.getAxisU(); + } + } + if (axis == undefined) { + error(localize("Polar interpolation requires an active rotary axis be defined in direction of workplane normal.")); + } + + // calculate directional vector from initial position + if (direction == undefined) { + error(localize("Polar interpolation initiated without a directional vector.")); + return; + } else if (direction.isZero()) { + var initialPosition = getFramePosition(section.getInitialPosition()); + direction = Vector.diff(initialPosition, axis.getOffset()).getNormalized(); + } + + // put vector in plane of rotary axis + var temp = Vector.cross(direction, axis.getAxis()).getNormalized(); + direction = Vector.cross(axis.getAxis(), temp).getNormalized(); + + // activate polar interpolation + saveTcpIsSupported = tcpIsSupported; + tcpIsSupported = false; // temporary disable tcp support for polar mode + setFeedrateMode(); + activatePolarMode(tolerance / 2, 0, direction); +} +// End of polar interpolation + +function onCircular(clockwise, cx, cy, cz, x, y, z, feed) { + if (isSpiral()) { + var startRadius = getCircularStartRadius(); + var endRadius = getCircularRadius(); + var dr = Math.abs(endRadius - startRadius); + if (dr > maximumCircularRadiiDifference) { // maximum limit + linearize(tolerance); // or alternatively use other G-codes for spiral motion + return; + } + } + + if (pendingRadiusCompensation >= 0) { + error(localize("Radius compensation cannot be activated/deactivated for a circular move.")); + return; + } + + var start = getCurrentPosition(); + + if (isFullCircle()) { + if (getProperty("useRadius") || isHelical()) { // radius mode does not support full arcs + linearize(tolerance); + return; + } + switch (getCircularPlane()) { + case PLANE_XY: + writeBlock(gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), getFeed(feed)); + break; + case PLANE_ZX: + writeBlock(gPlaneModal.format(18), gMotionModal.format(clockwise ? 2 : 3), iOutput.format(cx - start.x, 0), kOutput.format(cz - start.z, 0), getFeed(feed)); + break; + case PLANE_YZ: + writeBlock(gPlaneModal.format(19), gMotionModal.format(clockwise ? 2 : 3), jOutput.format(cy - start.y, 0), kOutput.format(cz - start.z, 0), getFeed(feed)); + break; + default: + linearize(tolerance); + } + } else if (!getProperty("useRadius")) { + switch (getCircularPlane()) { + case PLANE_XY: + writeBlock(gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), getFeed(feed)); + break; + case PLANE_ZX: + writeBlock(gPlaneModal.format(18), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), iOutput.format(cx - start.x, 0), kOutput.format(cz - start.z, 0), getFeed(feed)); + break; + case PLANE_YZ: + writeBlock(gPlaneModal.format(19), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), jOutput.format(cy - start.y, 0), kOutput.format(cz - start.z, 0), getFeed(feed)); + break; + default: + linearize(tolerance); + } + } else { // use radius mode + var r = getCircularRadius(); + if (toDeg(getCircularSweep()) > (180 + 1e-9)) { + r = -r; // allow up to <360 deg arcs + } + switch (getCircularPlane()) { + case PLANE_XY: + writeBlock(gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), "R" + rFormat.format(r), getFeed(feed)); + break; + case PLANE_ZX: + writeBlock(gPlaneModal.format(18), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), "R" + rFormat.format(r), getFeed(feed)); + break; + case PLANE_YZ: + writeBlock(gPlaneModal.format(19), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), "R" + rFormat.format(r), getFeed(feed)); + break; + default: + linearize(tolerance); + } + } +} + +var currentCoolantMode = COOLANT_OFF; +var coolantOff = undefined; +var isOptionalCoolant = false; + +function setCoolant(coolant) { + var coolantCodes = getCoolantCodes(coolant); + forceSingleLine = false; + if ((coolantCodes != undefined) && (coolant == COOLANT_FLOOD)) { + if (coolantPressure != "") { + forceSingleLine = true; + coolantCodes.push(coolantPressure); + } + } + if (Array.isArray(coolantCodes)) { + if (singleLineCoolant || forceSingleLine) { + skipBlock = isOptionalCoolant; + writeBlock(coolantCodes.join(getWordSeparator())); + } else { + for (var c in coolantCodes) { + skipBlock = isOptionalCoolant; + writeBlock(coolantCodes[c]); + } + } + return undefined; + } + return coolantCodes; +} + +var isSpecialCoolantActive = false; + +function getCoolantCodes(coolant) { + isOptionalCoolant = false; + var multipleCoolantBlocks = new Array(); // create a formatted array to be passed into the outputted line + if (!coolants) { + error(localize("Coolants have not been defined.")); + } + if (isProbeOperation()) { // avoid coolant output for probing + coolant = COOLANT_OFF; + } + if (coolant == currentCoolantMode) { + if (operationNeedsSafeStart && coolant != COOLANT_OFF && !isSpecialCoolantActive) { + isOptionalCoolant = true; + } else if (!forceCoolant || coolant == COOLANT_OFF) { + return undefined; // coolant is already active + } + } + if ((coolant != COOLANT_OFF) && (currentCoolantMode != COOLANT_OFF) && !isOptionalCoolant && !forceCoolant) { + if (Array.isArray(coolantOff)) { + for (var i in coolantOff) { + multipleCoolantBlocks.push(mFormat.format(coolantOff[i])); + } + } else { + multipleCoolantBlocks.push(mFormat.format(coolantOff)); + } + } + forceCoolant = false; + + if (isSpecialCoolantActive) { + forceSpindleSpeed = true; + } + var m; + var coolantCodes = {}; + for (var c in coolants) { // find required coolant codes into the coolants array + if (coolants[c].id == coolant) { + isSpecialCoolantActive = (coolants[c].id == COOLANT_THROUGH_TOOL) || (coolants[c].id == COOLANT_FLOOD_THROUGH_TOOL) || (coolants[c].id == COOLANT_AIR_THROUGH_TOOL); + 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(mFormat.format(m[i])); + } + } else { + multipleCoolantBlocks.push(mFormat.format(m)); + } + currentCoolantMode = coolant; + return multipleCoolantBlocks; // return the single formatted coolant value + } + return undefined; +} + +var mapCommand = { + COMMAND_END:2, + COMMAND_SPINDLE_CLOCKWISE:3, + COMMAND_SPINDLE_COUNTERCLOCKWISE:4, + COMMAND_STOP_SPINDLE:5, + COMMAND_ORIENTATE_SPINDLE:19, + COMMAND_LOAD_TOOL:6 +}; + +function onCommand(command) { + switch (command) { + case COMMAND_STOP: + writeBlock(mFormat.format(0)); + forceSpindleSpeed = true; + forceCoolant = true; + return; + case COMMAND_OPTIONAL_STOP: + writeBlock(mFormat.format(1)); + forceSpindleSpeed = true; + currentCoolantMode = COOLANT_OFF; + forceCoolant = true; + return; + case COMMAND_COOLANT_ON: + setCoolant(COOLANT_FLOOD); + return; + case COMMAND_COOLANT_OFF: + setCoolant(COOLANT_OFF); + return; + case COMMAND_START_SPINDLE: + onCommand(tool.clockwise ? COMMAND_SPINDLE_CLOCKWISE : COMMAND_SPINDLE_COUNTERCLOCKWISE); + return; + case COMMAND_LOCK_MULTI_AXIS: + if (machineConfiguration.isMultiAxisConfiguration() && (machineConfiguration.getNumberOfAxes() >= 4)) { + var _skipBlock = skipBlock; + writeBlock(mFormat.format(10)); // lock 4th-axis motion + if (machineConfiguration.getNumberOfAxes() == 5) { + skipBlock = _skipBlock; + writeBlock(mFormat.format(12)); // lock 5th-axis motion + } + } + return; + case COMMAND_UNLOCK_MULTI_AXIS: + if (machineConfiguration.isMultiAxisConfiguration() && (machineConfiguration.getNumberOfAxes() >= 4)) { + var _skipBlock = skipBlock; + writeBlock(mFormat.format(11)); // unlock 4th-axis motion + if (machineConfiguration.getNumberOfAxes() == 5) { + skipBlock = _skipBlock; + writeBlock(mFormat.format(13)); // unlock 5th-axis motion + } + } + return; + case COMMAND_BREAK_CONTROL: + if (!toolChecked) { // avoid duplicate COMMAND_BREAK_CONTROL + prepareForToolCheck(); + writeBlock( + gFormat.format(65), + "P" + 9853, + "T" + toolFormat.format(tool.number), + "B" + xyzFormat.format(0), + "H" + xyzFormat.format(getProperty("toolBreakageTolerance")) + ); + toolChecked = true; + lengthCompensationActive = false; // macro 9853 cancels tool length compensation + } + return; + case COMMAND_TOOL_MEASURE: + measureTool = true; + return; + case COMMAND_START_CHIP_TRANSPORT: + writeBlock(mFormat.format(31)); + return; + case COMMAND_STOP_CHIP_TRANSPORT: + writeBlock(mFormat.format(33)); + 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); + } +} + +var toolChecked = false; // specifies that the tool has been checked with the probe + +function onSectionEnd() { + if (isInspectionOperation() && !isLastSection()) { + writeBlock(gFormat.format(103), "P0", formatComment("LOOKAHEAD ON")); + } + if (!isLastSection() && (getNextSection().getTool().coolant != tool.coolant)) { + setCoolant(COOLANT_OFF); + } + if ((((getCurrentSectionId() + 1) >= getNumberOfSections()) || + (tool.number != getNextSection().getTool().number)) && + tool.breakControl) { + onCommand(COMMAND_BREAK_CONTROL); + } else { + toolChecked = false; + } + + if (true) { + if (isRedirecting()) { + if (firstPattern) { + var finalPosition = getFramePosition(currentSection.getFinalPosition()); + var abc; + if (currentSection.isMultiAxis() && machineConfiguration.isMultiAxisConfiguration()) { + abc = currentSection.getFinalToolAxisABC(); + } else { + abc = currentWorkPlaneABC; + } + if (abc == undefined) { + abc = new Vector(0, 0, 0); + } + setAbsoluteMode(finalPosition, abc); + subprogramEnd(); + } + } + } + forceAny(); + + if (currentSection.isMultiAxis()) { + writeBlock(gFeedModeModal.format(94)); // inverse time feed off + if (currentSection.isOptimizedForMachine()) { + // the code below gets the machine angles from previous operation. closestABC must also be set to true + currentMachineABC = currentSection.getFinalToolAxisABC(); + } + if (tcpIsSupported) { + disableLengthCompensation(false, "TCPC OFF"); + } + } + + if (isProbeOperation()) { + writeBlock(gFormat.format(65), "P" + 9833); // spin the probe off + if (probeVariables.probeAngleMethod != "G68") { + setProbeAngle(); // output probe angle rotations if required + } + } + + // reset for next section + operationNeedsSafeStart = false; + coolantPressure = getProperty("coolantPressure"); + cycleReverse = false; + + setPolarMode(currentSection, false); +} + +/** Output block to do safe retract and/or move to home position. */ +function writeRetract() { + var words = []; // store all retracted axes in an array + var retractAxes = new Array(false, false, false); + var method = getProperty("safePositionMethod"); + if (method == "clearanceHeight") { + if (!is3D()) { + error(localize("Retract option 'Clearance Height' is not supported for multi-axis machining.")); + } else { + return; + } + } + validate(arguments.length != 0, "No axis specified for writeRetract()."); + + for (i in arguments) { + retractAxes[arguments[i]] = true; + } + if ((retractAxes[0] || retractAxes[1]) && !retracted && !skipBlock) { // retract Z first before moving to X/Y home + error(localize("Retracting in X/Y is not possible without being retracted in Z.")); + return; + } + // special conditions + if (retractAxes[0] || retractAxes[1]) { + method = "G53"; + } + cancelG68Rotation(); // G68 has to be canceled for retracts + + // define home positions + var _xHome; + var _yHome; + var _zHome; + if (method == "G28") { + _xHome = toPreciseUnit(0, MM); + _yHome = toPreciseUnit(0, MM); + _zHome = toPreciseUnit(0, MM); + } else { + if (homePositionCenter && + hasParameter("part-upper-x") && hasParameter("part-lower-x")) { + _xHome = (getParameter("part-upper-x") + getParameter("part-lower-x")) / 2; + } else { + _xHome = machineConfiguration.hasHomePositionX() ? machineConfiguration.getHomePositionX() : toPreciseUnit(0, MM); + } + _yHome = machineConfiguration.hasHomePositionY() ? machineConfiguration.getHomePositionY() : toPreciseUnit(0, MM); + _zHome = machineConfiguration.getRetractPlane() != 0 ? machineConfiguration.getRetractPlane() : toPreciseUnit(0, MM); + } + for (var i = 0; i < arguments.length; ++i) { + switch (arguments[i]) { + case X: + // special conditions + if (homePositionCenter) { // output X in standard block by itself if centering + writeBlock(gMotionModal.format(0), "X" + xyzFormat.format(_xHome)); + xOutput.reset(); + break; + } + words.push("X" + xyzFormat.format(_xHome)); + xOutput.reset(); + break; + case Y: + words.push("Y" + xyzFormat.format(_yHome)); + yOutput.reset(); + break; + case Z: + words.push("Z" + xyzFormat.format(_zHome)); + zOutput.reset(); + retracted = !skipBlock; + break; + default: + error(localize("Unsupported axis specified for writeRetract().")); + return; + } + } + if (words.length > 0) { + switch (method) { + case "G28": + gMotionModal.reset(); + gAbsIncModal.reset(); + writeBlock(gFormat.format(28), gAbsIncModal.format(91), words); + writeBlock(gAbsIncModal.format(90)); + break; + case "G53": + gMotionModal.reset(); + writeBlock(gAbsIncModal.format(90), gFormat.format(53), gMotionModal.format(0), words); + break; + default: + error(localize("Unsupported safe position method.")); + return; + } + } +} + +var isDPRNTopen = false; +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, "-"); + writeln("DPRNT[START]"); + writeln("DPRNT[RESULTSFILE*" + resFile + "]"); + if (hasGlobalParameter("document-id")) { + writeln("DPRNT[DOCUMENTID*" + getGlobalParameter("document-id") + "]"); + } + if (hasGlobalParameter("model-version")) { + writeln("DPRNT[MODELVERSION*" + getGlobalParameter("model-version") + "]"); + } + } + if (isProbeOperation() && printProbeResults()) { + isDPRNTopen = true; + } +} + +function getPointNumber() { + if (typeof inspectionWriteVariables == "function") { + return (inspectionVariables.pointNumber); + } else { + return ("#172[60]"); + } +} + +function inspectionWriteCADTransform() { + var cadOrigin = currentSection.getModelOrigin(); + var cadWorkPlane = currentSection.getModelPlane().getTransposed(); + var cadEuler = cadWorkPlane.getEuler2(EULER_XYZ_S); + writeln( + "DPRNT[G331" + + "*N" + getPointNumber() + + "*A" + abcFormat.format(cadEuler.x) + + "*B" + abcFormat.format(cadEuler.y) + + "*C" + abcFormat.format(cadEuler.z) + + "*X" + xyzFormat.format(-cadOrigin.x) + + "*Y" + xyzFormat.format(-cadOrigin.y) + + "*Z" + xyzFormat.format(-cadOrigin.z) + + "]" + ); +} + +function inspectionWriteWorkplaneTransform() { + var orientation = (machineConfiguration.isMultiAxisConfiguration() && currentMachineABC != undefined) ? machineConfiguration.getOrientation(currentMachineABC) : currentSection.workPlane; + var abc = orientation.getEuler2(EULER_XYZ_S); + writeln("DPRNT[G330" + + "*N" + getPointNumber() + + "*A" + abcFormat.format(abc.x) + + "*B" + abcFormat.format(abc.y) + + "*C" + abcFormat.format(abc.z) + + "*X0*Y0*Z0*I0*R0]" + ); +} + +function writeProbingToolpathInformation(cycleDepth) { + writeln("DPRNT[TOOLPATHID*" + getParameter("autodeskcam:operation-id") + "]"); + if (isInspectionOperation()) { + writeln("DPRNT[TOOLPATH*" + getParameter("operation-comment") + "]"); + } else { + writeln("DPRNT[CYCLEDEPTH*" + xyzFormat.format(cycleDepth) + "]"); + } +} + +function onClose() { + if (isDPRNTopen) { + writeln("DPRNT[END]"); + writeBlock("PCLOS"); + isDPRNTopen = false; + if (typeof inspectionProcessSectionEnd == "function") { + inspectionProcessSectionEnd(); + } + } + cancelG68Rotation(); + writeln(""); + + optionalSection = false; + + onCommand(COMMAND_STOP_SPINDLE); + onCommand(COMMAND_COOLANT_OFF); + + // retract + writeRetract(Z); + if (!getProperty("homePositionCenter") || currentMachineABC.length != 0) { + writeRetract(X, Y); + } + + if (activeG254) { + writeBlock(gFormat.format(255)); // cancel DWO + activeG254 = false; + } + + // MAY NEED CHANGE HOMING ORDER TO ROTARY THEN LINEAR FOR NON-UMC MACHINES + + // Unwind Rotary table at end + if (machineConfiguration.isMultiAxisConfiguration()) { + onCommand(COMMAND_UNLOCK_MULTI_AXIS); + if (machineConfiguration.isMachineCoordinate(2)) { + writeBlock(gFormat.format(28), gAbsIncModal.format(91), "C" + abcFormat.format(0)); + writeBlock(gAbsIncModal.format(90)); + } else if (machineConfiguration.isMachineCoordinate(1)) { + writeBlock(gFormat.format(28), gAbsIncModal.format(91), "B" + abcFormat.format(0)); + writeBlock(gAbsIncModal.format(90)); + } else if (machineConfiguration.isMachineCoordinate(0)) { + writeBlock(gFormat.format(28), gAbsIncModal.format(91), "A" + abcFormat.format(0)); + writeBlock(gAbsIncModal.format(90)); + } + gMotionModal.reset(); + writeBlock( + gMotionModal.format(0), + conditional(machineConfiguration.isMachineCoordinate(0), "A" + abcFormat.format(0)), + conditional(machineConfiguration.isMachineCoordinate(1), "B" + abcFormat.format(0)), + conditional(machineConfiguration.isMachineCoordinate(2), "C" + abcFormat.format(0)) + ); + } + if (getProperty("homePositionCenter")) { + homePositionCenter = getProperty("homePositionCenter"); + writeRetract(X, Y); + } + + onImpliedCommand(COMMAND_END); + onImpliedCommand(COMMAND_STOP_SPINDLE); + + if (getProperty("useM130PartImages") || getProperty("useM130ToolImages")) { + writeBlock(mFormat.format(131)); + } + writeBlock(mFormat.format(30)); // stop program, spindle stop, coolant off + if (subprograms.length > 0) { + writeln(""); + write(subprograms); + } + writeln(""); + writeln("%"); +} + +/* +keywords += (keywords ? " MODEL_IMAGE" : "MODEL_IMAGE"); + +function onTerminate() { + var outputPath = getOutputPath(); + var programFilename = FileSystem.getFilename(outputPath); + var programSize = FileSystem.getFileSize(outputPath); + var postPath = findFile("setup-sheet-excel-2007.cps"); + var intermediatePath = getIntermediatePath(); + var a = "--property unit " + ((unit == IN) ? "0" : "1"); // use 0 for inch and 1 for mm + if (programName) { + a += " --property programName \"'" + programName + "'\""; + } + if (programComment) { + a += " --property programComment \"'" + programComment + "'\""; + } + a += " --property programFilename \"'" + programFilename + "'\""; + a += " --property programSize \"" + programSize + "\""; + a += " --noeditor --log temp.log \"" + postPath + "\" \"" + intermediatePath + "\" \"" + FileSystem.replaceExtension(outputPath, "xlsx") + "\""; + execute(getPostProcessorPath(), a, false, ""); + executeNoWait("excel", "\"" + FileSystem.replaceExtension(outputPath, "xlsx") + "\"", false, ""); +} +*/ + +function setProperty(property, value) { + properties[property].current = value; +} +// <<<<< INCLUDED FROM ../../../haas next generation.cps + +capabilities |= CAPABILITY_INSPECTION; +description = "HAAS - Next Generation Control Inspect Surface"; +longDescription = "Generic post for the HAAS Next Generation control with inspect surface capabilities."; + +var controlType = "NGC"; // Specifies the control model "NGC" or "Classic" +// >>>>> INCLUDED FROM ../common/haas base inspection.cps +properties.probeLocalVar = { + title: "Local variable start", + description: "Specify the starting value for macro # variables that are to be used for calculations during inspection paths.", + group: 99, + type: "integer", + value: (controlType == "NGC" ? 10000 : 100), + scope: "post" +}; +properties.useDirectConnection = { + title: "Stream Measured Point Data", + description: "Set to true to stream inspection results.", + group: 99, + type: "boolean", + value: false, + scope: "post" +}; +properties.probeResultsBuffer = { + title: "Measurement results store start", + description: "Specify the starting value of macro # variables where measurement results are stored.", + group: 99, + type: "integer", + value: (controlType == "NGC" ? 10100 : 150), + scope: "post" +}; +properties.probeNumberofPoints = { + title: "Measurement number of points to store", + description: "This is the maximum number of measurement results that can be stored in the buffer.", + group: 99, + type: "integer", + value: 4, + scope: "post" +}; +properties.controlConnectorVersion = { + title: "Results connector version", + description: "Interface version for direct connection to read inspection results.", + group: 99, + type: "integer", + value: 1, + scope: "post" +}; +properties.toolOffsetType = { + title: "Tool offset type", + description: "Select the which offsets are available on the tool offset page.", + group: 99, + type: "enum", + values: [ + {id: "geomWear", title: "Geometry & Wear"}, + {id: "geomOnly", title: "Geometry only"} + ], + value: "geomWear", + scope: "post" +}; +properties.commissioningMode = { + title: "Inspection Commissioning Mode", + description: "Enables commissioning mode where M0 and messages are output at key points in the program.", + group: 99, + type: "boolean", + value: true, + scope: "post" +}; +properties.probeOnCommand = { + title: "Probe On Command", + description: "The command used to turn the probe on, this can be a M code or sub program call.", + group: 99, + type: "string", + value: "G65 P9832", + scope: "post" +}; +properties.probeOffCommand = { + title: "Probe Off Command", + description: "The command used to turn the probe off, this can be a M code or sub program call.", + group: 99, + type: "string", + value: "G65 P9833", + scope: "post" +}; +properties.probeCalibratedRadius = { + title: "Calibrated Radius", + description: "Macro Variable used for storing probe calibrated radi.", + group: 99, + type: "integer", + value: (controlType == "NGC" ? 10556 : 556), + scope: "post" +}; +properties.probeEccentricityX = { + title: "Eccentricity X", + description: "Macro Variable used for storing the X eccentricity.", + group: 99, + type: "integer", + value: (controlType == "NGC" ? 10558 : 558), + scope: "post" +}; +properties.probeEccentricityY = { + title: "Eccentricity Y", + description: "Macro Variable used for storing the Y eccentricity.", + group: 99, + type: "integer", + value: (controlType == "NGC" ? 10559 : 559), + scope: "post" +}; +properties.probeCalibrationMethod = { + title: "Probe calibration Method", + description: "Select the probe calibration method.", + group: 99, + type: "enum", + values: [ + {id: "Renishaw", title: "Renishaw"}, + {id: "Autodesk", title: "Autodesk"}, + {id: "Other", title: "Other"} + ], + value: "Renishaw", + scope: "post" +}; +properties.calibrationNCOutput = { + title: "Calibration NC Output Type", + description: "Choose none if the NC program created is to be used for calibrating the probe.", + group: 99, + type: "enum", + values: [ + {id: "none", title: "none"}, + {id: "Ring Gauge", title: "Ring Gauge"} + ], + value: "none", + scope: "post" +}; + +var ijkFormat = createFormat({decimals:5, forceDecimal:true}); +// inspection variables +var inspectionVariables = { + localVariablePrefix: "#", + probeRadius: 0, + systemVariableMeasuredX: 5061, + systemVariableMeasuredY: 5062, + systemVariableMeasuredZ: 5063, + pointNumber: 1, + probeResultsBufferFull: false, + probeResultsBufferIndex: 1, + hasInspectionSections: false, + inspectionSectionCount: 0, + systemVariableOffsetLengthTable: 2200, + systemVariableOffsetWearTable: 2000, + workpieceOffset: "", + systemVariablePreviousX: 5001, + systemVariablePreviousY: 5002, + systemVariablePreviousZ: 5003, + systemVariableCurrentX: 5021, + systemVariableCurrentY: 5022, + systemVariableCurrentZ: 5023, +}; + +var macroFormat = createFormat({prefix:inspectionVariables.localVariablePrefix, decimals:0}); +var LINEAR_MOVE = 1; +var SAFE_MOVE = 2; +var SAFE_MOVE_DWO = 3; +var MEASURE_MOVE = 4; +var ALARM_IF_DEFLECTED = "M78"; +var ALARM_IF_NOT_DEFLECTED = "M79"; +var NO_DEFLECTION_CHECK = ""; + +function inspectionWriteVariables() { + // loop through all NC stream sections to check for surface inspection + for (var i = 0; i < getNumberOfSections(); ++i) { + var section = getSection(i); + if (section.strategy == "inspectSurface") { + inspectionVariables.workpieceOffset = section.workOffset; + var count = 1; + var localVar = getProperty("probeLocalVar"); + var prefix = inspectionVariables.localVariablePrefix; + inspectionVariables.probeRadius = prefix + count; + inspectionVariables.xTarget = prefix + ++count; + inspectionVariables.yTarget = prefix + ++count; + inspectionVariables.zTarget = prefix + ++count; + inspectionVariables.xMeasured = prefix + ++count; + inspectionVariables.yMeasured = prefix + ++count; + inspectionVariables.zMeasured = prefix + ++count; + inspectionVariables.activeToolLength = prefix + ++count; + inspectionVariables.macroVariable1 = prefix + ++count; + inspectionVariables.macroVariable2 = prefix + ++count; + inspectionVariables.macroVariable3 = prefix + ++count; + inspectionVariables.macroVariable4 = prefix + ++count; + inspectionVariables.macroVariable5 = prefix + ++count; + inspectionVariables.macroVariable6 = prefix + ++count; + inspectionVariables.macroVariable7 = prefix + ++count; + inspectionVariables.wcsVectorX = prefix + ++count; + inspectionVariables.wcsVectorY = prefix + ++count; + inspectionVariables.wcsVectorZ = prefix + ++count; + inspectionVariables.previousWCSX = prefix + ++count; + inspectionVariables.previousWCSY = prefix + ++count; + inspectionVariables.previousWCSZ = prefix + ++count; + if (getProperty("calibrationNCOutput") == "Ring Gauge") { + inspectionVariables.measuredXStartingAddress = localVar; + inspectionVariables.measuredYStartingAddress = localVar + 10; + inspectionVariables.measuredZStartingAddress = localVar + 20; + inspectionVariables.measuredIStartingAddress = localVar + 30; + inspectionVariables.measuredJStartingAddress = localVar + 40; + inspectionVariables.measuredKStartingAddress = localVar + 50; + } + inspectionValidateInspectionSettings(); + inspectionVariables.probeResultsReadPointer = prefix + (getProperty("probeResultsBuffer") + 2); + inspectionVariables.probeResultsWritePointer = prefix + (getProperty("probeResultsBuffer") + 3); + inspectionVariables.probeResultsCollectionActive = prefix + (getProperty("probeResultsBuffer") + 4); + inspectionVariables.probeResultsStartAddress = getProperty("probeResultsBuffer") + 5; + if (getProperty("toolOffsetType") == "geomOnly") { + inspectionVariables.systemVariableOffsetLengthTable = "2000"; + } + if (getProperty("commissioningMode")) { + writeBlock("#3006=1" + formatComment("Inspection commissioning mode is active, when the machine is measuring correctly please disable this in the post properties")); + } + if (getProperty("useDirectConnection")) { + // check to make sure local variables used in results buffer and inspection do not clash + var localStart = getProperty("probeLocalVar"); + var localEnd = count; + var BufferStart = getProperty("probeResultsBuffer"); + var bufferEnd = getProperty("probeResultsBuffer") + ((3 * getProperty("probeNumberofPoints")) + 8); + if ((localStart >= BufferStart && localStart <= bufferEnd) || (localEnd >= BufferStart && localEnd <= bufferEnd)) { + error("Local variables defined (" + prefix + localStart + "-" + prefix + localEnd + + ") and live probe results storage area (" + prefix + BufferStart + "-" + prefix + bufferEnd + ") overlap." + ); + } + writeBlock(macroFormat.format(getProperty("probeResultsBuffer")) + " = " + getProperty("controlConnectorVersion")); + writeBlock(macroFormat.format(getProperty("probeResultsBuffer") + 1) + " = " + getProperty("probeNumberofPoints")); + writeBlock(inspectionVariables.probeResultsReadPointer + " = 0"); + writeBlock(inspectionVariables.probeResultsWritePointer + " = 1"); + writeBlock(inspectionVariables.probeResultsCollectionActive + " = 0"); + if (getProperty("probeResultultsBuffer") == 0) { + error("Probe Results Buffer start address cannot be zero when using a direct connection."); + } + inspectionWriteFusionConnectorInterface("HEADER"); + } + inspectionVariables.hasInspectionSections = true; + break; + } + } +} + +function onProbe(status) { + if (status) { // probe ON + if (getProperty("commissioningMode") && getProperty("calibrationNCOutput") == "Ring Gauge") { + writeBlock(mFormat.format(19), "R#1"); + } else { + writeBlock(mFormat.format(19)); + } + writeBlock(getProperty("probeOnCommand")); // Command for switching the probe on + onDwell(2); + if (getProperty("commissioningMode")) { + writeBlock("#3006=1" + formatComment("Ensure Probe Is Active")); + } + } else { // probe OFF + writeBlock(getProperty("probeOffCommand")); // Command for switching the probe off + onDwell(2); + if (getProperty("commissioningMode")) { + writeBlock("#3006=1" + formatComment("Ensure Probe Has Deactivated")); + } + } +} + +function inspectionCycleInspect(cycle, x, y, z) { + if (getNumberOfCyclePoints() != 3) { + error(localize("Missing Endpoint in Inspection Cycle, check Approach and Retract heights")); + } + forceFeed(); // ensure feed is always output - just incase. + if (isFirstCyclePoint()) { + writeComment("Approach Move"); + // safe move to approach point start + if (activeG254) { + // Apply Eccentricity + gMotionModal.reset(); + writeBlock(gFormat.format(61)); //exact stop mode on + writeBlock(gAbsIncModal.format(91), gFormat.format(1), + "X-" + macroFormat.format(getProperty("probeEccentricityX")), + "Y-" + macroFormat.format(getProperty("probeEccentricityY")), + feedOutput.format(cycle.safeFeed) + ); + writeBlock(gFormat.format(103), "P1", formatComment("LOOKAHEAD OFF")); + inspectionGetCoordinates(true); + inspectionCalculateTargetEndpoint(x, y, z, SAFE_MOVE_DWO); + // move alond probing vector with DWO off + inspectionWriteCycleMove(gAbsIncModal.format(91), cycle.safeFeed, SAFE_MOVE_DWO, ALARM_IF_DEFLECTED); + // Apply radius delta correction + writeBlock(gAbsIncModal.format(91), gFormat.format(1), + "Z+[" + xyzFormat.format(tool.diameter / 2) + "-" + inspectionVariables.probeRadius + "]", + feedOutput.format(cycle.safeFeed) + ); + writeBlock(gFormat.format(103), "P1", formatComment("LOOKAHEAD OFF")); + inspectionGetCoordinates(false); + } else { + // only do trigger check when DWO is not active + inspectionCalculateTargetEndpoint(x, y, z, SAFE_MOVE); + inspectionWriteCycleMove(gAbsIncModal.format(90), cycle.safeFeed, SAFE_MOVE, ALARM_IF_DEFLECTED); + } + return; + } + if (isLastCyclePoint()) { + // retract move + writeComment("Retract Move"); + inspectionCalculateTargetEndpoint(x, y, z, LINEAR_MOVE); + inspectionWriteCycleMove(gAbsIncModal.format(90), cycle.linkFeed, LINEAR_MOVE, NO_DEFLECTION_CHECK); + forceXYZ(); + writeBlock(gFormat.format(64)); //exact stop mode on + return; + } + // measure move + if (getProperty("commissioningMode") && (inspectionVariables.pointNumber == 1)) { + writeBlock("#3006=1" + formatComment("Probe is about to contact part. Axes should stop on contact")); + } + inspectionWriteNominalData(cycle); + if (getProperty("useDirectConnection")) { + inspectionWriteFusionConnectorInterface("MEASURE"); + } + inspectionCalculateTargetEndpoint(x, y, z, MEASURE_MOVE); + var f = cycle.measureFeed; + if (activeG254) { + inspectionWriteCycleMove(gAbsIncModal.format(91), f, MEASURE_MOVE, ALARM_IF_NOT_DEFLECTED); + writeBlock(inspectionVariables.xTarget + "=" + macroFormat.format(inspectionVariables.systemVariableMeasuredX)); + writeBlock(inspectionVariables.yTarget + "=" + macroFormat.format(inspectionVariables.systemVariableMeasuredY)); + writeBlock(inspectionVariables.zTarget + "=" + macroFormat.format(inspectionVariables.systemVariableMeasuredZ) + " - " + inspectionVariables.activeToolLength); + inspectionWriteCycleMove(gAbsIncModal.format(90), f, LINEAR_MOVE, NO_DEFLECTION_CHECK); + inspectionReconfirmPositionDWO(f); + } else { + inspectionWriteCycleMove(gAbsIncModal.format(90), f, MEASURE_MOVE, ALARM_IF_NOT_DEFLECTED); + } + inspectionCorrectProbeMeasurement(); + inspectionWriteMeasuredData(); +} + +function inspectionWriteNominalData(cycle) { + var m = getRotation(); + var v = new Vector(cycle.nominalX, cycle.nominalY, cycle.nominalZ); + var vt = m.multiply(v); + var pathVector = new Vector(cycle.nominalI, cycle.nominalJ, cycle.nominalK); + var nv = m.multiply(pathVector).normalized; + cycle.nominalX = vt.x; + cycle.nominalY = vt.y; + cycle.nominalZ = vt.z; + cycle.nominalI = nv.x; + cycle.nominalJ = nv.y; + cycle.nominalK = nv.z; + writeln("DPRNT[G800" + + "*N" + inspectionVariables.pointNumber + + "*X" + xyzFormat.format(cycle.nominalX) + + "*Y" + xyzFormat.format(cycle.nominalY) + + "*Z" + xyzFormat.format(cycle.nominalZ) + + "*I" + ijkFormat.format(cycle.nominalI) + + "*J" + ijkFormat.format(cycle.nominalJ) + + "*K" + ijkFormat.format(cycle.nominalK) + + "*O" + xyzFormat.format(getParameter("operation:inspectSurfaceOffset")) + + "*U" + xyzFormat.format(getParameter("operation:inspectUpperTolerance")) + + "*L" + xyzFormat.format(getParameter("operation:inspectLowerTolerance")) + + "]" + ); +} + +function inspectionCalculateTargetEndpoint(x, y, z, moveType) { + writeComment("CALCULATE TARGET ENDPOINT"); + if (activeG254 && (moveType == MEASURE_MOVE || moveType == SAFE_MOVE_DWO)) { + // get measure move vector with TWP active + var searchIJK = new Vector(0, 0, 0); + var searchDistance; + var moveDistance; + + switch (moveType) { + case MEASURE_MOVE: + // writeComment("CTE - MEASURE_MOVE"); + searchDistance = getParameter("probeClearance") + getParameter("probeOvertravel"); + moveDistance = searchDistance * 0.1; + searchDistance -= moveDistance; + searchIJK.i = cycle.nominalI * -1 * moveDistance; + searchIJK.j = cycle.nominalJ * -1 * moveDistance; + searchIJK.k = cycle.nominalK * -1 * moveDistance; + break; + case SAFE_MOVE_DWO: + // get safe move unit vector with DWO active + // writeComment("CTE - SAFE_MOVE_DWO"); + var xyz = new Vector(0, 0, 0); + xyz = getCurrentPosition(); + var vectorI = x - xyz.x; + var vectorJ = y - xyz.y; + var vectorK = z - xyz.z; + var magnitude = Math.sqrt((vectorI * vectorI) + (vectorJ * vectorJ) + (vectorK * vectorK)); + moveDistance = magnitude * 0.1; + searchIJK.i = (vectorI / magnitude) * moveDistance; + searchIJK.j = (vectorJ / magnitude) * moveDistance; + searchIJK.k = (vectorK / magnitude) * moveDistance; + searchDistance = magnitude - moveDistance; + break; + default: + // writeComment("CTE - DEFAULT"); + } + // xyzTarget is previous move endpoint - with eccentricity correction + writeBlock(inspectionVariables.xTarget + " =" + xyzFormat.format(searchIJK.i)); + writeBlock(inspectionVariables.yTarget + " =" + xyzFormat.format(searchIJK.j)); + writeBlock(inspectionVariables.zTarget + " =" + xyzFormat.format(searchIJK.k)); + inspectionWriteCycleMove(gAbsIncModal.format(91), moveType == MEASURE_MOVE ? cycle.measureFeed : cycle.safeFeed, LINEAR_MOVE, NO_DEFLECTION_CHECK); + writeBlock(gFormat.format(255)); + writeComment("Calculate vector in WPCS"); + writeBlock(inspectionVariables.wcsVectorX + " =" + macroFormat.format(inspectionVariables.systemVariableCurrentX) + "-" + inspectionVariables.previousWCSX); + writeBlock(inspectionVariables.wcsVectorY + " =" + macroFormat.format(inspectionVariables.systemVariableCurrentY) + "-" + inspectionVariables.previousWCSY); + writeBlock(inspectionVariables.wcsVectorZ + " =[" + macroFormat.format(inspectionVariables.systemVariableCurrentZ) + "-" + inspectionVariables.activeToolLength + "]-" + inspectionVariables.previousWCSZ); + writeBlock(inspectionVariables.macroVariable4 + " =SQRT[" + + "[" + inspectionVariables.wcsVectorX + "*" + inspectionVariables.wcsVectorX + "]" + "+" + + "[" + inspectionVariables.wcsVectorY + "*" + inspectionVariables.wcsVectorY + "]" + "+" + + "[" + inspectionVariables.wcsVectorZ + "*" + inspectionVariables.wcsVectorZ + "]]" + ); + writeComment("Convert to unit vector"); + // safe or measure move endpointwith DWO active + writeBlock(inspectionVariables.xTarget + " =[" + xyzFormat.format(searchDistance) + " * [" + inspectionVariables.wcsVectorX + "/" + inspectionVariables.macroVariable4 + "]]"); + writeBlock(inspectionVariables.yTarget + " =[" + xyzFormat.format(searchDistance) + " * [" + inspectionVariables.wcsVectorY + "/" + inspectionVariables.macroVariable4 + "]]"); + writeBlock(inspectionVariables.zTarget + " =[" + xyzFormat.format(searchDistance) + " * [" + inspectionVariables.wcsVectorZ + "/" + inspectionVariables.macroVariable4 + "]]"); + } else { + writeBlock(inspectionVariables.xTarget + " =" + xyzFormat.format(x) + "-" + macroFormat.format(getProperty("probeEccentricityX"))); + writeBlock(inspectionVariables.yTarget + " =" + xyzFormat.format(y) + "-" + macroFormat.format(getProperty("probeEccentricityY"))); + writeBlock(inspectionVariables.zTarget + " =" + xyzFormat.format(z) + "+[" + xyzFormat.format(tool.diameter / 2) + "-" + inspectionVariables.probeRadius + "]"); + } +} + +function inspectionWriteCycleMove(absInc, feedRate, moveType, triggerCheck) { + // writeComment("moveType = " + moveType, triggerCheck); + var motionCommand = moveType == LINEAR_MOVE ? 1 : 31; + gMotionModal.reset(); + writeBlock(absInc, + gFormat.format(motionCommand), + "X" + inspectionVariables.xTarget, + "Y" + inspectionVariables.yTarget, + "Z" + inspectionVariables.zTarget, + feedOutput.format(feedRate), + triggerCheck + ); + writeBlock(gFormat.format(103), "P1", formatComment("LOOKAHEAD OFF")); +} + +function inspectionProbeTriggerCheck(triggered) { + var condition = triggered ? " GT " : " LT "; + var message = triggered ? "NO POINT TAKEN" : "PATH OBSTRUCTED"; + var inPositionTolerance = (unit == MM) ? 0.01 : 0.0004; + writeBlock(inspectionVariables.macroVariable1 + " =" + inspectionVariables.xTarget + "-" + macroFormat.format(inspectionVariables.systemVariableMeasuredX)); + writeBlock(inspectionVariables.macroVariable2 + " =" + inspectionVariables.yTarget + "-" + macroFormat.format(inspectionVariables.systemVariableMeasuredY)); + writeBlock(inspectionVariables.macroVariable3 + " =" + inspectionVariables.zTarget + "-" + macroFormat.format(inspectionVariables.systemVariableMeasuredZ) + "+" + inspectionVariables.activeToolLength); + writeBlock(inspectionVariables.macroVariable4 + " =" + + "[" + inspectionVariables.macroVariable1 + "*" + inspectionVariables.macroVariable1 + "]" + "+" + + "[" + inspectionVariables.macroVariable2 + "*" + inspectionVariables.macroVariable2 + "]" + "+" + + "[" + inspectionVariables.macroVariable3 + "*" + inspectionVariables.macroVariable3 + "]" + ); + forceSequenceNumbers(true); + writeBlock("IF [" + inspectionVariables.macroVariable4 + condition + inPositionTolerance + "] GOTO" + skipNLines(2)); + writeBlock("#3000 = 1 " + formatComment(message)); + writeBlock(" "); + forceSequenceNumbers(false); +} + +function inspectionCorrectProbeMeasurement() { + writeComment("Correct Measurements"); + var MeasuredX = macroFormat.format(inspectionVariables.systemVariableMeasuredX); + var MeasuredY = macroFormat.format(inspectionVariables.systemVariableMeasuredY); + var MeasuredZ = macroFormat.format(inspectionVariables.systemVariableMeasuredZ); + if (activeG254) { + // Actual is previous target system parameter - with eccentricity correction + MeasuredX = macroFormat.format(inspectionVariables.systemVariablePreviousX); + MeasuredY = macroFormat.format(inspectionVariables.systemVariablePreviousY); + MeasuredZ = macroFormat.format(inspectionVariables.systemVariablePreviousZ); + } + writeBlock(inspectionVariables.xMeasured + " =" + MeasuredX + "+" + macroFormat.format(getProperty("probeEccentricityX"))); + writeBlock(inspectionVariables.yMeasured + " =" + MeasuredY + "+" + macroFormat.format(getProperty("probeEccentricityY"))); + // need to consider probe centre tool output point in future too + var correctToolLength = activeG254 ? "" : ("-" + inspectionVariables.activeToolLength); + writeBlock(inspectionVariables.zMeasured + " =" + MeasuredZ + "+" + inspectionVariables.probeRadius + correctToolLength); +} + +function inspectionWriteFusionConnectorInterface(ncSection) { + if (ncSection == "MEASURE") { + writeBlock("IF " + inspectionVariables.probeResultsCollectionActive + " NE 1 GOTO " + inspectionVariables.pointNumber); + writeBlock("WHILE [" + inspectionVariables.probeResultsReadPointer + " EQ " + inspectionVariables.probeResultsWritePointer + "] DO 1"); + onDwell(0.5); + writeComment("WAITING FOR FUSION CONNECTION"); + writeBlock("G53"); + writeBlock("END 1"); + writeBlock("N" + inspectionVariables.pointNumber); + } else { + writeBlock("WHILE [" + inspectionVariables.probeResultsCollectionActive + " NE 1] DO 1"); + onDwell(0.5); + writeComment("WAITING FOR FUSION CONNECTION"); + writeBlock("G53"); + writeBlock("END 1"); + } +} + +function inspectionCalculateDeviation() { + var outputFormat = (unit == MM) ? "[53]" : "[44]"; + //calculate the deviation and produce a warning if out of tolerance. + //(Measured + ((vector *(-1))*calibrated radi)) + + writeComment("calculate deviation"); + //compensate for tip rad in X + writeBlock( + inspectionVariables.macroVariable1 + "=[" + + inspectionVariables.xMeasured + "+[[" + + ijkFormat.format(cycle.nominalI) + "*[-1]]*" + + inspectionVariables.probeRadius + "]]" + ); + //compensate for tip rad in Y + writeBlock( + inspectionVariables.macroVariable2 + "=[" + + inspectionVariables.yMeasured + "+[[" + + ijkFormat.format(cycle.nominalJ) + "*[-1]]*" + + inspectionVariables.probeRadius + "]]" + ); + //compensate for tip rad in Z + writeBlock( + inspectionVariables.macroVariable3 + "=[" + + inspectionVariables.zMeasured + "+[[" + + ijkFormat.format(cycle.nominalK) + "*[-1]]*" + + inspectionVariables.probeRadius + "]]" + ); + //Calculate deviation vector (Measured x - nominal x) + writeBlock( + inspectionVariables.macroVariable4 + "=" + + inspectionVariables.macroVariable1 + "-" + + xyzFormat.format(cycle.nominalX) + ); + //Calculate deviation vector (Measured y - nominal y) + writeBlock( + inspectionVariables.macroVariable5 + "=" + + inspectionVariables.macroVariable2 + "-" + + xyzFormat.format(cycle.nominalY) + ); + //Calculate deviation vector (Measured Z - nominal Z) + writeBlock( + inspectionVariables.macroVariable6 + "=[" + + inspectionVariables.macroVariable3 + "-[" + + xyzFormat.format(cycle.nominalZ) + "]]" + ); + //sqrt xyz.xyz this is the value of the deviation + writeBlock( + inspectionVariables.macroVariable7 + "=SQRT[[" + + inspectionVariables.macroVariable4 + "*" + + inspectionVariables.macroVariable4 + "]+[" + + inspectionVariables.macroVariable5 + "*" + + inspectionVariables.macroVariable5 + "]+[" + + inspectionVariables.macroVariable6 + "*" + + inspectionVariables.macroVariable6 + "]]" + ); + //sign of the vector + writeBlock( + inspectionVariables.macroVariable1 + "=[[" + + ijkFormat.format(cycle.nominalI) + "*" + + inspectionVariables.macroVariable4 + "]+[" + + ijkFormat.format(cycle.nominalJ) + "*" + + inspectionVariables.macroVariable5 + "]+[" + + ijkFormat.format(cycle.nominalK) + "*" + + inspectionVariables.macroVariable6 + "]]" + ); + //Print out deviation value + forceSequenceNumbers(true); + writeBlock( + "IF [" + inspectionVariables.macroVariable1 + "GE0] GOTO" + skipNLines(3) + ); + writeBlock( + inspectionVariables.macroVariable4 + "=" + + inspectionVariables.macroVariable7 + ); + writeBlock("GOTO" + skipNLines(2)); + writeBlock( + inspectionVariables.macroVariable4 + "=[" + + inspectionVariables.macroVariable7 + "*[-1]]" + ); + writeBlock(" "); + writeln( + "DPRNT[G802" + "*N" + inspectionVariables.pointNumber + + "*DEVIATION*" + inspectionVariables.macroVariable4 + outputFormat + "]" + ); + //Tolerance check + writeBlock( + "IF [" + inspectionVariables.macroVariable4 + + "LT" + (xyzFormat.format(getParameter("operation:inspectUpperTolerance"))) + + "] GOTO" + skipNLines(3) + ); + writeBlock( + "#3006 = 1" + formatComment("Inspection point over tolerance") + ); + writeBlock("GOTO" + skipNLines(3)); + writeBlock( + "IF [" + inspectionVariables.macroVariable4 + + "GT" + (xyzFormat.format(getParameter("operation:inspectLowerTolerance"))) + + "] GOTO" + skipNLines(2) + ); + writeBlock( + "#3006 = 1" + formatComment("Inspection point under tolerance") + ); + writeBlock(" "); + forceSequenceNumbers(false); +} + +function inspectionWriteMeasuredData() { + var outputFormat = (unit == MM) ? "[53]" : "[44]"; + writeln("DPRNT[G801" + + "*N" + inspectionVariables.pointNumber + + "*X" + inspectionVariables.xMeasured + outputFormat + + "*Y" + inspectionVariables.yMeasured + outputFormat + + "*Z" + inspectionVariables.zMeasured + outputFormat + + "*R" + inspectionVariables.probeRadius + outputFormat + + "]" + ); + + if (cycle.outOfPositionAction == "stop-message") { + inspectionCalculateDeviation(); + } + + if (getProperty("useDirectConnection")) { + var writeResultIndexX = inspectionVariables.probeResultsStartAddress + (3 * inspectionVariables.probeResultsBufferIndex); + var writeResultIndexY = inspectionVariables.probeResultsStartAddress + (3 * inspectionVariables.probeResultsBufferIndex) + 1; + var writeResultIndexZ = inspectionVariables.probeResultsStartAddress + (3 * inspectionVariables.probeResultsBufferIndex) + 2; + + writeBlock(macroFormat.format(writeResultIndexX) + " = " + inspectionVariables.xMeasured); + writeBlock(macroFormat.format(writeResultIndexY) + " = " + inspectionVariables.yMeasured); + writeBlock(macroFormat.format(writeResultIndexZ) + " = " + inspectionVariables.zMeasured); + inspectionVariables.probeResultsBufferIndex += 1; + if (inspectionVariables.probeResultsBufferIndex > getProperty("probeNumberofPoints")) { + inspectionVariables.probeResultsBufferIndex = 0; + } + writeBlock(inspectionVariables.probeResultsWritePointer + " = " + inspectionVariables.probeResultsBufferIndex); + } + if (getProperty("commissioningMode") && (getProperty("calibrationNCOutput") == "Ring Gauge")) { + writeBlock(macroFormat.format(inspectionVariables.measuredXStartingAddress + inspectionVariables.pointNumber) + + " =" + inspectionVariables.xMeasured); + writeBlock(macroFormat.format(inspectionVariables.measuredYStartingAddress + inspectionVariables.pointNumber) + + " =" + inspectionVariables.yMeasured); + writeBlock(macroFormat.format(inspectionVariables.measuredZStartingAddress + inspectionVariables.pointNumber) + + " =" + inspectionVariables.zMeasured); + writeBlock(macroFormat.format(inspectionVariables.measuredIStartingAddress + inspectionVariables.pointNumber) + + " =" + xyzFormat.format(cycle.nominalI)); + writeBlock(macroFormat.format(inspectionVariables.measuredJStartingAddress + inspectionVariables.pointNumber) + + " =" + xyzFormat.format(cycle.nominalJ)); + writeBlock(macroFormat.format(inspectionVariables.measuredKStartingAddress + inspectionVariables.pointNumber) + + " =" + xyzFormat.format(cycle.nominalK)); + } + inspectionVariables.pointNumber += 1; +} + +function forceSequenceNumbers(force) { + if (force) { + setProperty("showSequenceNumbers", true); + } else { + setProperty("showSequenceNumbers", saveShowSequenceNumbers); + } +} + +function skipNLines(n) { + return (n * getProperty("sequenceNumberIncrement") + sequenceNumber); +} + +function inspectionProcessSectionStart() { + writeBlock(gFormat.format(103), "P1", formatComment("LOOKAHEAD OFF")); + // only write header once if user selects a single results file + if (!isDPRNTopen || !getProperty("singleResultsFile") || (currentSection.workOffset != inspectionVariables.workpieceOffset)) { + inspectionCreateResultsFileHeader(); + inspectionVariables.workpieceOffset = currentSection.workOffset; + } + // write the toolpath name as a comment + writeProbingToolpathInformation(); + inspectionWriteCADTransform(); + inspectionWriteWorkplaneTransform(); + inspectionVariables.inspectionSectionCount += 1; + if (getProperty("toolOffsetType") == "geomOnly") { + writeComment("Geometry Only"); + writeBlock( + inspectionVariables.activeToolLength + "=" + + inspectionVariables.localVariablePrefix + "[" + + inspectionVariables.systemVariableOffsetLengthTable + " + " + + macroFormat.format(4111) + + "]" + ); + } else { + writeComment("Geometry and Wear"); + writeBlock( + inspectionVariables.activeToolLength + "=" + + inspectionVariables.localVariablePrefix + "[" + + inspectionVariables.systemVariableOffsetLengthTable + " + " + + macroFormat.format(4111) + + "] + " + + inspectionVariables.localVariablePrefix + "[" + + inspectionVariables.systemVariableOffsetWearTable + " + " + + macroFormat.format(4111) + + "]" + ); + } + if (getProperty("probeCalibrationMethod") == "Renishaw") { + writeBlock(inspectionVariables.probeRadius + "=[[" + + macroFormat.format(getProperty("probeCalibratedRadius")) + " + " + + macroFormat.format(getProperty("probeCalibratedRadius") + 1) + "]" + "/2]" + ); + } else { + writeBlock(inspectionVariables.probeRadius + "=" + macroFormat.format(getProperty("probeCalibratedRadius"))); + } + if (getProperty("commissioningMode") && !isDPRNTopen) { + var outputFormat = (unit == MM) ? "[53]" : "[44]"; + writeln("DPRNT[CALIBRATED*RADIUS*" + inspectionVariables.probeRadius + outputFormat + "]"); + writeln("DPRNT[ECCENTRICITY*X****" + macroFormat.format(getProperty("probeEccentricityX")) + outputFormat + "]"); + writeln("DPRNT[ECCENTRICITY*Y****" + macroFormat.format(getProperty("probeEccentricityY")) + outputFormat + "]"); + forceSequenceNumbers(true); + writeBlock("IF [" + inspectionVariables.probeRadius + " NE #0] GOTO" + skipNLines(2)); + writeBlock("#3000 = 1" + formatComment("PROBE NOT CALIBRATED OR PROPERTY CALIBRATED RADIUS INCORRECT")); + writeBlock("IF [" + inspectionVariables.probeRadius + " NE 0] GOTO" + skipNLines(2)); + writeBlock("#3000 = 1" + formatComment("PROBE NOT CALIBRATED OR PROPERTY CALIBRATED RADIUS INCORRECT")); + writeBlock("IF [" + inspectionVariables.probeRadius + " LT " + xyzFormat.format(tool.diameter / 2) + "] GOTO" + skipNLines(2)); + writeBlock("#3000 = 1" + formatComment("PROBE NOT CALIBRATED OR PROPERTY CALIBRATED RADIUS INCORRECT")); + var maxEccentricity = (unit == MM) ? 0.2 : 0.0079; + writeBlock("IF [ABS[" + macroFormat.format(getProperty("probeEccentricityX")) + "] LT " + maxEccentricity + "] GOTO" + skipNLines(2)); + writeBlock("#3000 = 1" + formatComment("PROBE NOT CALIBRATED OR PROPERTY ECCENTRICITY X INCORRECT")); + writeBlock("IF [ABS[" + macroFormat.format(getProperty("probeEccentricityY")) + "] LT " + maxEccentricity + "] GOTO" + skipNLines(2)); + writeBlock("#3000 = 1" + formatComment("PROBE NOT CALIBRATED OR PROPERTY ECCENTRICITY Y INCORRECT")); + writeBlock("IF [" + macroFormat.format(getProperty("probeEccentricityX")) + " NE #0] GOTO" + skipNLines(2)); + writeBlock("#3000 = 1" + formatComment("PROBE NOT CALIBRATED OR PROPERTY ECCENTRICITY X INCORRECT")); + writeBlock("IF [" + macroFormat.format(getProperty("probeEccentricityY")) + " NE #0] GOTO" + skipNLines(2)); + writeBlock("#3000 = 1" + formatComment("PROBE NOT CALIBRATED OR PROPERTY ECCENTRICITY Y INCORRECT")); + writeBlock(" "); + forceSequenceNumbers(false); + } + isDPRNTopen = true; +} + +function inspectionProcessSectionEnd() { + // close inspection results file if the NC has inspection toolpaths + if (inspectionVariables.hasInspectionSections) { + if (getProperty("commissioningMode")) { + if (controlType == "NGC") { + forceSequenceNumbers(true); + writeBlock(inspectionVariables.macroVariable1 + " = [#20261 * " + 4 * getProperty("sequenceNumberIncrement") + " + " + skipNLines(2) + "]"); + writeBlock("GOTO " + inspectionVariables.macroVariable1); + writeBlock(" "); + writeBlock("#3006=1" + formatComment("DPRNT LOCATION NOT SET")); + onCommand(COMMAND_STOP); + writeBlock("GOTO " + skipNLines(8)); + writeBlock(" "); + writeBlock("#3006=1" + formatComment("CHECK SETTING 262 FOR RESULTS FILE LOCATION")); + onCommand(COMMAND_STOP); + writeBlock("GOTO " + skipNLines(4)); + writeBlock(" "); + writeBlock("#3006=1" + formatComment("RESULTS FILE WRITTEN TO TCP PORT")); + onCommand(COMMAND_STOP); + writeBlock(" "); + forceSequenceNumbers(false); + } else { + writeBlock("#3006=1" + formatComment("RESULTS FILE WRITTEN TO SERIAL PORT")); + } + } + writeBlock(gFormat.format(103), "P0", formatComment("LOOKAHEAD ON")); + } +} + +function inspectionGetCoordinates(isApproachMove) { + if (isApproachMove) { + writeComment("Get Current Point DWO ON"); + writeBlock(inspectionVariables.xTarget + " =" + macroFormat.format(inspectionVariables.systemVariablePreviousX)); + writeBlock(inspectionVariables.yTarget + " =" + macroFormat.format(inspectionVariables.systemVariablePreviousY)); + writeBlock(inspectionVariables.zTarget + " =" + macroFormat.format(inspectionVariables.systemVariablePreviousZ)); + } + writeComment("Current Point in WCS"); + writeBlock(gFormat.format(255)); + writeBlock(inspectionVariables.previousWCSX + " =" + macroFormat.format(inspectionVariables.systemVariableCurrentX)); + writeBlock(inspectionVariables.previousWCSY + " =" + macroFormat.format(inspectionVariables.systemVariableCurrentY)); + writeBlock(inspectionVariables.previousWCSZ + " =" + macroFormat.format(inspectionVariables.systemVariableCurrentZ) + "-" + inspectionVariables.activeToolLength); + inspectionReconfirmPositionDWO(cycle.safeFeed); +} + +function inspectionReconfirmPositionDWO(f) { + // zero length move to re-confirm current position + writeComment("Re-confirm position DWO Active"); + writeBlock(gFormat.format(254)); + writeBlock(gAbsIncModal.format(91), gMotionModal.format(1), "X0.0 Y0.0", feedOutput.format(f)); + writeBlock("Z0.0"); + writeBlock(gFormat.format(103), "P1", formatComment("LOOKAHEAD OFF")); +} +// <<<<< INCLUDED FROM ../common/haas base inspection.cps + +function inspectionValidateInspectionSettings() { + var errorText = ""; + if (getProperty("probeOnCommand") == "") { + errorText += "\n-Probe On Command-"; + } + if (getProperty("probeOffCommand") == "") { + errorText += "\n-Probe Off Command-"; + } + if (getProperty("probeCalibratedRadius") == 0) { + errorText += "\n-Calibrated Radius-"; + } + if (getProperty("probeEccentricityX") == 0) { + errorText += "\n-Eccentricity X-"; + } + if (getProperty("probeEccentricityY") == 0) { + errorText += "\n-Eccentricity Y-"; + } + if (errorText != "") { + error(localize("The following properties need to be configured:" + errorText + "\n-Please consult the guide PDF found at https://cam.autodesk.com/hsmposts?p=haas_next_generation_inspect_surface for more information-")); + } +} From 47d2726149c76cda1ac5b3dc16ea3199c35bd641 Mon Sep 17 00:00:00 2001 From: will1742 Date: Mon, 14 Jun 2021 16:50:33 -0400 Subject: [PATCH 2/7] Basic M130 Functinality --- Haas_Next_Generation/haas vf2.cps | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/Haas_Next_Generation/haas vf2.cps b/Haas_Next_Generation/haas vf2.cps index c910818..da684cb 100644 --- a/Haas_Next_Generation/haas vf2.cps +++ b/Haas_Next_Generation/haas vf2.cps @@ -2332,9 +2332,9 @@ function onSection() { } } - var inMapping = takeInput("Y/N?", ['Y', 'N', 'X', 'Y', 'Z']); - writeln(inMapping) - + displayMedia("testfile.png"); + takeInput("Y/N", ['Y', 'N']); + cancelMedia(); // Modified 06/09/21 | Gavin Williams | will1742 // Issue 000 Init coolant after positioning setCoolant(tool.coolant); @@ -2344,6 +2344,22 @@ function onSection() { } // Added 6/14/21 | Gavin Williams | will1742 +// Issue 001 Input and Validation +// Displays a file: MP4, MOV, PNG, JPEG. 1920x1080 +// Input: Absolute path to file +function displayMedia(file) { + writeln("N" + sequenceNumber + " M130 (" + file + ")"); + sequenceNumber += getProperty("sequenceNumberIncrement"); +} + +// Ends displayed media +function cancelMedia() { + writeln("N" + sequenceNumber + " M131 (End Media)"); + sequenceNumber += getProperty("sequenceNumberIncrement"); +} + +// Added 6/14/21 | Gavin Williams | will1742 +// Issue 001 Input and Validation // Takes input from the user // Input: string prompt, will be displayed to users // char array options, capital letters accepted as input From b606085a04de161b23bc644abb50fc21c607ccca Mon Sep 17 00:00:00 2001 From: will1742 Date: Tue, 15 Jun 2021 16:31:45 -0400 Subject: [PATCH 3/7] Added basic validation and QA --- Haas_Next_Generation/haas next generation.cps | 3545 ----------------- Haas_Next_Generation/haas vf2.cps | 41 +- 2 files changed, 38 insertions(+), 3548 deletions(-) delete mode 100644 Haas_Next_Generation/haas next generation.cps diff --git a/Haas_Next_Generation/haas next generation.cps b/Haas_Next_Generation/haas next generation.cps deleted file mode 100644 index 8d85afc..0000000 --- a/Haas_Next_Generation/haas next generation.cps +++ /dev/null @@ -1,3545 +0,0 @@ -/** - Copyright (C) 2012-2019 by Autodesk, Inc. - All rights reserved. - - HAAS post processor configuration. - - $Revision: 42601 95324a72443c22406fe893c91f874e4f0971d5c4 $ - $Date: 2019-12-04 06:35:42 $ - - FORKID {DBD402DA-DE90-4634-A6A3-0AE5CC97DEC7} -*/ - -description = "HAAS - Next Generation Control"; -vendor = "Haas Automation"; -vendorUrl = "https://www.haascnc.com"; -legal = "Copyright (C) 2012-2019 by Autodesk, Inc."; -certificationLevel = 2; -minimumRevision = 40783; - -longDescription = "Generic post for the HAAS Next Generation control. The post includes support for multi-axis indexing and simultaneous machining. The post utilizes the dynamic work offset feature so you can place your work piece as desired without having to repost your NC programs."; - -extension = "nc"; -programNameIsInteger = true; -setCodePage("ascii"); - -capabilities = CAPABILITY_MILLING; -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(355); -allowHelicalMoves = true; -allowedCircularPlanes = undefined; // allow any circular motion -allowSpiralMoves = true; -highFeedrate = (unit == IN) ? 650 : 5000; // up to 650 should be supported - -// user-defined properties -properties = { - writeMachine: false, // write machine - writeTools: true, // writes the tools - writeVersion: true, // include version info - preloadTool: true, // preloads next tool on tool change if any - chipTransport: false, // turn on chip transport at start of program - showSequenceNumbers: true, // show sequence numbers - sequenceNumberStart: 10, // first sequence number - sequenceNumberIncrement: 5, // increment for sequence numbers - sequenceNumberOnlyOnToolChange: false, // only output sequence numbers on tool change - optionalStop: true, // optional stop - separateWordsWithSpace: true, // specifies that the words should be separated with a white space - useRadius: false, // specifies that arcs should be output using the radius (R word) instead of the I, J, and K words. - useParametricFeed: false, // specifies that feed should be output using Q values - showNotes: true, // specifies that operation notes should be output - useG0: true, // allow G0 when moving along more than one axis - useG28: false, // specifies that G28 should be used instead of G53 - useSubroutines: false, // specifies that subroutines should be generated - useSubroutinePatterns: false, // generates subroutines for patterned operation - useSubroutineCycles: false, // generates subroutines for cycle operations on same holes - useG187: false, // use G187 to set smoothing on the machine - homePositionCenter: true, // moves the part in X in center of the door at end of program (ONLY WORKS IF THE TABLE IS MOVING) - optionallyCycleToolsAtStart: false, // cycle through each tool used at the beginning of the program when block delete is turned off - this allows the operator to easily measure all tools before they are used for the first run of the program - optionallyMeasureToolsAtStart: false, // measure each tool used at the beginning of the program when block delete is turned off - this allows the operator to easily measure all tools before they are used for the first run of the program - hasAAxis: "false", // configures A axis - hasBAxis: "false", // configures B axis - hasCAxis: "false", // configures C axis - toolBreakageTolerance: 0.1, // value for which tool break detection will raise an alarm - safeStartAllOperations: false, // write optional blocks at the beginning of all operations that include all commands to start program - fastToolChange: false, // skip spindle off, coolant off, and Z retract to make tool change quicker - useG95forTapping: false, // use IPR/MPR instead of IPM/MPM for tapping - safeRetractDistance: 0.0, // distance to add to retract distance when rewinding rotary axes - useDPMFeeds: false, // output DPM feeds instead of Inverse Time feeds - useTCPC: true, // enable/disable TCPC option - useDWO: true // Dynamic Work Offset (DWO), like CYCL 19 -}; - -propertyDefinitions = { - writeMachine: {title:"Write machine", description:"Output the machine settings in the header of the code.", group:0, type:"boolean"}, - writeTools: {title:"Write tool list", description:"Output a tool list in the header of the code.", group:0, type:"boolean"}, - writeVersion: {title:"Write version", description:"Write the version number in the header of the code.", group:0, type:"boolean"}, - preloadTool: {title:"Preload tool", description:"Preloads the next tool at a tool change (if any).", type:"boolean"}, - chipTransport: {title:"Use chip transport", description:"Enable to turn on chip transport at start of program.", type:"boolean"}, - showSequenceNumbers: {title:"Use sequence numbers", description:"Use sequence numbers for each block of outputted code.", group:1, type:"boolean"}, - sequenceNumberStart: {title:"Start sequence number", description:"The number at which to start the sequence numbers.", group:1, type:"integer"}, - sequenceNumberIncrement: {title:"Sequence number increment", description:"The amount by which the sequence number is incremented by in each block.", group:1, type:"integer"}, - sequenceNumberOnlyOnToolChange: {title:"Block number only on tool change", description:"Specifies that block numbers should only be output at tool changes.", type:"boolean"}, - optionalStop: {title:"Optional stop", description:"Specifies that optional stops M1 should be output at tool changes.", type:"boolean"}, - separateWordsWithSpace: {title:"Separate words with space", description:"Adds spaces between words if 'yes' is selected.", type:"boolean"}, - useRadius: {title:"Radius arcs", description:"If yes is selected, arcs are output using radius values rather than IJK.", type:"boolean"}, - useParametricFeed: {title:"Parametric feed", description:"Parametric feed values based on movement type are output.", type:"boolean"}, - showNotes: {title:"Show notes", description:"Enable to output notes for operations.", type:"boolean"}, - useG0: {title:"Use G0", description:"Specifies that G0s should be used for rapid moves when moving along a single axis.", type:"boolean"}, - useG28: {title:"Use G28 instead of G53", description:"Specifies that machine retracts should be done using G28 instead of G53.", type:"boolean"}, - useSubroutines: {title:"Use subroutines", description:"Enables output of subroutines for each operation.", type:"boolean"}, - useSubroutinePatterns: {title:"Subroutines for patterns", description:"Enable output of subroutines for patterns.", type:"boolean"}, - useSubroutineCycles: {title:"Subroutines for cycles", description:"Enable output of subroutines for cycles.", type:"boolean"}, - useG187: {title:"Use G187", description:"Specifies that smoothing using G187 should be used.", type:"boolean"}, - homePositionCenter: {title:"Home position center", description:"Enable to center the part along X at the end of program for easy access. Requires a CNC with a moving table.", type:"boolean"}, - optionallyCycleToolsAtStart: {title:"Optionally cycle tools at start", description:"Cycle through each tool used at the beginning of the program when block delete is turned off.", type:"boolean"}, - optionallyMeasureToolsAtStart: {title:"Optionally measure tools at start", description:"Measure each tool used at the beginning of the program when block delete is turned off.", type:"boolean"}, - hasAAxis: { - title: "Has A-axis rotary", - description: "Enable if the machine has an A-axis table/trunnion. Check the table direction on the machine and use the (Reversed) selection if the table is moving in the opposite direction.", - type: "enum", - values:[ - {title:"No", id:"false"}, - {title:"Yes", id:"true"}, - {title:"Reversed", id:"reversed"} - ] - }, - hasBAxis: { - title: "Has B-axis rotary", - description: "Enable if the machine has a B-axis table/trunnion. Check the table direction on the machine and use the (Reversed) selection if the table is moving in the opposite direction.", - type: "enum", - values:[ - {title:"No", id:"false"}, - {title:"Yes", id:"true"}, - {title:"Reversed", id:"reversed"} - ] - }, - hasCAxis: { - title: "Has C-axis rotary", - description: "Enable if the machine has a C-axis table. Specifies a trunnion setup if an A-axis or B-axis is defined. Check the table direction on the machine and use the (Reversed) selection if the table is moving in the opposite direction.", - type: "enum", - values:[ - {title:"No", id:"false"}, - {title:"Yes", id:"true"}, - {title:"Reversed", id:"reversed"} - ] - }, - toolBreakageTolerance: {title:"Tool breakage tolerance", description:"Specifies the tolerance for which tool break detection will raise an alarm.", type:"spatial"}, - safeStartAllOperations: {title:"Safe start all operations", description:"Write optional blocks at the beginning of all operations that include all commands to start program.", type:"boolean"}, - fastToolChange: {title:"Fast tool change", description:"Skip spindle off, coolant off, and Z retract to make tool change quicker.", type:"boolean"}, - useG95forTapping: {title:"Use G95 for tapping", description:"use IPR/MPR instead of IPM/MPM for tapping", type:"boolean"}, - safeRetractDistance: {title:"Safe retract distance", description:"Specifies the distance to add to retract distance when rewinding rotary axes.", type:"spatial"}, - useDPMFeeds: {title:"Rotary moves use IPM feeds", description:"Enable to output IPM feeds, disable for Inverse Time feeds with rotary axes moves.", type:"boolean"}, - useTCPC: {title:"Use TCPC programming", description:"The control supports Tool Center Point Control programming.", type:"boolean"}, - useDWO: {title:"Use DWO", description:"Specifies that the Dynamic Work Offset feature (G254/G255) should be used.", type:"boolean"} -}; - -var singleLineCoolant = false; // specifies to output multiple coolant codes in one line rather than in separate lines -// samples: -// {id: COOLANT_THROUGH_TOOL, on: 88, off: 89} -// {id: COOLANT_THROUGH_TOOL, on: [8, 88], off: [9, 89]} -var coolants = [ - {id: COOLANT_FLOOD, on: 8}, - {id: COOLANT_MIST}, - {id: COOLANT_THROUGH_TOOL, on: 88, off: 89}, - {id: COOLANT_AIR, on: 83, off: 84}, - {id: COOLANT_AIR_THROUGH_TOOL, on: 73, off: 74}, - {id: COOLANT_SUCTION}, - {id: COOLANT_FLOOD_MIST}, - {id: COOLANT_FLOOD_THROUGH_TOOL, on: [88, 8], off: [89, 9]}, - {id: COOLANT_OFF, off: 9} -]; - -// old machines only support 4 digits -var oFormat = createFormat({width:5, zeropad:true, decimals:0}); -var nFormat = createFormat({decimals:0}); - -var gFormat = createFormat({prefix:"G", decimals:0}); -var mFormat = createFormat({prefix:"M", decimals:0}); -var hFormat = createFormat({prefix:"H", decimals:0}); -var dFormat = createFormat({prefix:"D", decimals:0}); -var probe154Format = createFormat({decimals:0, zeropad:true, width:2}); - -var xyzFormat = createFormat({decimals:(unit == MM ? 3 : 4), forceDecimal:true}); -var rFormat = xyzFormat; // radius -var abcFormat = createFormat({decimals:3, forceDecimal:true, scale:DEG}); -var feedFormat = createFormat({decimals:(unit == MM ? 2 : 3), forceDecimal:true}); -var pitchFormat = createFormat({decimals:(unit == MM ? 3 : 4), forceDecimal:true}); -var toolFormat = createFormat({decimals:0}); -var rpmFormat = createFormat({decimals:0}); -var secFormat = createFormat({decimals:3, forceDecimal:true}); // seconds - range 0.001-1000 -var milliFormat = createFormat({decimals:0}); // milliseconds // range 1-9999 -var taperFormat = createFormat({decimals:1, scale:DEG}); - -var xOutput = createVariable({prefix:"X"}, xyzFormat); -var yOutput = createVariable({prefix:"Y"}, xyzFormat); -var zOutput = createVariable({onchange: function() {retracted = false;}, prefix:"Z"}, xyzFormat); -var aOutput = createVariable({prefix:"A"}, abcFormat); -var bOutput = createVariable({prefix:"B"}, abcFormat); -var cOutput = createVariable({prefix:"C"}, abcFormat); -var feedOutput = createVariable({prefix:"F"}, feedFormat); -var inverseTimeOutput = createVariable({prefix:"F", force:true}, feedFormat); -var pitchOutput = createVariable({prefix:"F", force:true}, pitchFormat); -var sOutput = createVariable({prefix:"S", force:true}, rpmFormat); -var dOutput = createVariable({}, dFormat); - -// circular output -var iOutput = createReferenceVariable({prefix:"I", force:true}, xyzFormat); -var jOutput = createReferenceVariable({prefix:"J", force:true}, xyzFormat); -var kOutput = createReferenceVariable({prefix:"K", force:true}, xyzFormat); - -var gMotionModal = createModal({}, gFormat); // modal group 1 // G0-G3, ... -var gPlaneModal = createModal({onchange:function () {gMotionModal.reset();}}, gFormat); // modal group 2 // G17-19 -var gAbsIncModal = createModal({}, gFormat); // modal group 3 // G90-91 -var gFeedModeModal = createModal({}, gFormat); // modal group 5 // G93-94 -var gUnitModal = createModal({}, gFormat); // modal group 6 // G20-21 -var gCycleModal = createModal({}, gFormat); // modal group 9 // G81, ... -var gRetractModal = createModal({force:true}, gFormat); // modal group 10 // G98-99 -var gRotationModal = createModal({}, gFormat); // modal group 16 // G68-G69 - -// fixed settings -var firstFeedParameter = 100; // the first variable to use with parametric feed -var forceResetWorkPlane = false; // enable to force reset of machine ABC on new orientation -var minimumCyclePoints = 5; // minimum number of points in cycle operation to consider for subprogram -var useDwoForPositioning = true; // specifies to use the DWO feature for XY positioning for multi-axis operations - -var WARNING_WORK_OFFSET = 0; - -var ANGLE_PROBE_NOT_SUPPORTED = 0; -var ANGLE_PROBE_USE_ROTATION = 1; -var ANGLE_PROBE_USE_CAXIS = 2; - -var SUB_UNKNOWN = 0; -var SUB_PATTERN = 1; -var SUB_CYCLE = 2; - -// collected state -var sequenceNumber; -var currentWorkOffset; -var optionalSection = false; -var forceSpindleSpeed = false; -var activeMovements; // do not use by default -var currentFeedId; -var maximumCircularRadiiDifference = toPreciseUnit(0.005, MM); -var maximumLineLength = 80; // the maximum number of charaters allowed in a line -var g68RotationMode = 0; -var angularProbingMode; -var subprograms = []; -var currentPattern = -1; -var firstPattern = false; -var currentSubprogram; -var lastSubprogram; -var initialSubprogramNumber = 90000; -var definedPatterns = new Array(); -var incrementalMode = false; -var saveShowSequenceNumbers; -var cycleSubprogramIsActive = false; -var patternIsActive = false; -var lastOperationComment = ""; -var incrementalSubprogram; -var retracted = false; // specifies that the tool has been retracted to the safe plane -var hasA = false; -var hasB = false; -var hasC = false; -var measureTool = false; -probeMultipleFeatures = true; - -// used to convert blocks to optional for safeStartAllOperations, might get used outside of onSection -var operationNeedsSafeStart = false; -var operationNeedsSafeToolCall = false; -var operationNeedsSafeWorkOffset = false; -var operationNeedsSafeWorkPlane = false; -var operationNeedsSafeCoolant = false; - -/** - Writes the specified block. -*/ -var skipBlock = false; -function writeBlock() { - var text = formatWords(arguments); - if (!text) { - return; - } - var maximumSequenceNumber = (properties.useSubroutines || properties.useSubroutinePatterns || - properties.useSubroutineCycles) ? initialSubprogramNumber : 99999; - if (properties.showSequenceNumbers) { - if (sequenceNumber >= maximumSequenceNumber) { - sequenceNumber = properties.sequenceNumberStart; - } - if (optionalSection || skipBlock) { - if (text) { - writeWords("/", "N" + sequenceNumber, text); - } - } else { - writeWords2("N" + sequenceNumber, arguments); - } - sequenceNumber += properties.sequenceNumberIncrement; - } else { - if (optionalSection || skipBlock) { - writeWords2("/", arguments); - } else { - writeWords(arguments); - } - } - skipBlock = false; -} - -/** - Writes the specified block - used for tool changes only. -*/ -function writeToolBlock() { - var show = properties.showSequenceNumbers; - properties.showSequenceNumbers = show || properties.sequenceNumberOnlyOnToolChange; - writeBlock(arguments); - properties.showSequenceNumbers = show; -} - -/** - Writes the specified optional block. -*/ -function writeOptionalBlock() { - skipBlock = true; - writeBlock(arguments); -} - -function formatComment(text) { - return "(" + String(text).replace(/[()]/g, "") + ")"; -} - -/** - Output a comment. -*/ -function writeComment(text) { - writeln(formatComment(text.substr(0, maximumLineLength - 2))); -} - -/** - Returns the matching HAAS tool type for the tool. -*/ -function getHaasToolType(toolType) { - switch (toolType) { - case TOOL_DRILL: - case TOOL_REAMER: - return 1; // drill - case TOOL_TAP_RIGHT_HAND: - case TOOL_TAP_LEFT_HAND: - return 2; // tap - case TOOL_MILLING_FACE: - case TOOL_MILLING_SLOT: - case TOOL_BORING_BAR: - return 3; // shell mill - case TOOL_MILLING_END_FLAT: - case TOOL_MILLING_END_BULLNOSE: - case TOOL_MILLING_TAPERED: - case TOOL_MILLING_DOVETAIL: - return 4; // end mill - case TOOL_DRILL_SPOT: - case TOOL_MILLING_CHAMFER: - case TOOL_DRILL_CENTER: - case TOOL_COUNTER_SINK: - case TOOL_COUNTER_BORE: - case TOOL_MILLING_THREAD: - case TOOL_MILLING_FORM: - return 5; // center drill - case TOOL_MILLING_END_BALL: - case TOOL_MILLING_LOLLIPOP: - return 6; // ball nose - case TOOL_PROBE: - return 7; // probe - default: - error(localize("Invalid HAAS tool type.")); - return -1; - } -} - -function getHaasProbingType(toolType, use9023) { - switch (getHaasToolType(toolType)) { - case 3: - return (use9023 ? 23 : 1); // rotate - case 4: - return (use9023 ? 13 : 3); // rotate length and dia - case 1: - case 2: - case 5: - case 6: - case 7: - return (use9023 ? 12 : 2); // non rotate - case 0: - default: - error(localize("Invalid HAAS tool type.")); - return -1; - } -} - -function writeToolCycleBlock(tool) { - writeOptionalBlock("T" + toolFormat.format(tool.number), mFormat.format(6)); // get tool - writeOptionalBlock(mFormat.format(0)); // wait for operator -} - -function writeToolMeasureBlock(tool) { - var writeFunction = measureTool ? writeBlock : writeOptionalBlock; - var comment = measureTool ? formatComment("MEASURE TOOL") : ""; - if (true) { // use Macro P9023 to measure tools - var probingType = getHaasProbingType(tool.type, true); - writeFunction( - gFormat.format(65), - "P9023", - "A" + probingType + ".", - "T" + toolFormat.format(tool.number), - conditional((probingType != 12), "H" + xyzFormat.format(tool.bodyLength + tool.holderLength)), - conditional((probingType != 12), "D" + xyzFormat.format(tool.diameter)), - comment - ); - } else { // use Macro P9995 to measure tools - writeFunction("T" + toolFormat.format(tool.number), mFormat.format(6)); // get tool - writeFunction( - gFormat.format(65), - "P9995", - "A0.", - "B" + getHaasToolType(tool.type) + ".", - "C" + getHaasProbingType(tool.type, false) + ".", - "T" + toolFormat.format(tool.number), - "E" + xyzFormat.format(tool.bodyLength + tool.holderLength), - "D" + xyzFormat.format(tool.diameter), - "K" + xyzFormat.format(0.1), - "I0.", - comment - ); // probe tool - } - measureTool = false; -} - -function onOpen() { - if (properties.useDPMFeeds) { - gFeedModeModal.format(94); - } - if (properties.useRadius) { - maximumCircularSweep = toRad(90); // avoid potential center calculation errors for CNC - } - if (properties.sequenceNumberOnlyOnToolChange) { - properties.showSequenceNumbers = false; - } - if (!properties.useDWO) { - useDwoForPositioning = false; - } - - gRotationModal.format(69); // Default to G69 Rotation Off - - hasA = properties.hasAAxis != "false"; - hasB = properties.hasBAxis != "false"; - hasC = properties.hasCAxis != "false"; - - if (hasA && hasB && hasC) { - error(localize("Only two rotary axes can be active at the same time.")); - return; - } - - if (true) { // configure machine - var aAxis; - var bAxis; - var cAxis; - - if (hasA) { // A Axis - For horizontal machines and trunnions - var dir = properties.hasAAxis == "reversed" ? -1 : 1; - if (hasC || hasB) { - var aMin = (dir == 1) ? -120 - 0.0001 : -30 - 0.0001; - var aMax = (dir == 1) ? 30 + 0.0001 : 120 + 0.0001; - aAxis = createAxis({coordinate:0, table:true, axis:[dir, 0, 0], range:[aMin, aMax], preference:dir}); - } else { - aAxis = createAxis({coordinate:0, table:true, axis:[dir, 0, 0], cyclic:true}); - } - } - - if (hasB) { // B Axis - For horizontal machines and trunnions - var dir = properties.hasBAxis == "reversed" ? -1 : 1; - if (hasC) { - var bMin = (dir == 1) ? -120 - 0.0001 : -30 - 0.0001; - var bMax = (dir == 1) ? 30 + 0.0001 : 120 + 0.0001; - bAxis = createAxis({coordinate:1, table:true, axis:[0, dir, 0], range:[bMin, bMax], preference:-dir}); - } else if (hasA) { - bAxis = createAxis({coordinate:1, table:true, axis:[0, 0, dir], cyclic:true}); - } else { - bAxis = createAxis({coordinate:1, table:true, axis:[0, dir, 0], cyclic:true}); - } - } - - if (hasC) { // C Axis - For trunnions only - var dir = properties.hasCAxis == "reversed" ? -1 : 1; - cAxis = createAxis({coordinate:2, table:true, axis:[0, 0, dir], cyclic:true}); - } - - if (hasA && hasC) { // AC trunnion - machineConfiguration = new MachineConfiguration(aAxis, cAxis); - } else if (hasB && hasC) { // BC trunnion - machineConfiguration = new MachineConfiguration(bAxis, cAxis); - } else if (hasA && hasB) { // AB trunnion - machineConfiguration = new MachineConfiguration(aAxis, bAxis); - } else if (hasA) { // A rotary - machineConfiguration = new MachineConfiguration(aAxis); - } else if (hasB) { // B rotary - horizontal machine only - machineConfiguration = new MachineConfiguration(bAxis); - } - - if (hasA || hasB || hasC) { - setMachineConfiguration(machineConfiguration); - optimizeMachineAngles2(properties.useTCPC ? 0 : 1); // map tip mode - } - } - - if (!machineConfiguration.isMachineCoordinate(0)) { - aOutput.disable(); - } - if (!machineConfiguration.isMachineCoordinate(1)) { - bOutput.disable(); - } - if (!machineConfiguration.isMachineCoordinate(2)) { - cOutput.disable(); - } - - if (highFeedrate <= 0) { - error(localize("You must set 'highFeedrate' because axes are not synchronized for rapid traversal.")); - return; - } - - if (!properties.separateWordsWithSpace) { - setWordSeparator(""); - } - - sequenceNumber = properties.sequenceNumberStart; - writeln("%"); - - if (programName) { - var programId; - try { - programId = getAsInt(programName); - } catch (e) { - error(localize("Program name must be a number.")); - return; - } - if (!((programId >= 1) && (programId <= 99999))) { - error(localize("Program number is out of range.")); - return; - } - writeln( - "O" + oFormat.format(programId) + - conditional(programComment, " " + formatComment(programComment.substr(0, maximumLineLength - 2 - ("O" + oFormat.format(programId)).length - 1))) - ); - lastSubprogram = (initialSubprogramNumber - 1); - } else { - error(localize("Program name has not been specified.")); - return; - } - - if (properties.useG0) { - writeComment(localize("Using G0 which travels along dogleg path.")); - } else { - writeComment(subst(localize("Using high feed G1 F%1 instead of G0."), feedFormat.format(highFeedrate))); - } - - if (properties.writeVersion) { - if ((typeof getHeaderVersion == "function") && getHeaderVersion()) { - writeComment(localize("post version") + ": " + getHeaderVersion()); - } - if ((typeof getHeaderDate == "function") && getHeaderDate()) { - writeComment(localize("post modified") + ": " + getHeaderDate()); - } - } - - // dump machine configuration - var vendor = machineConfiguration.getVendor(); - var model = machineConfiguration.getModel(); - var description = machineConfiguration.getDescription(); - - if (properties.writeMachine && (vendor || model || description)) { - writeComment(localize("Machine")); - if (vendor) { - writeComment(" " + localize("vendor") + ": " + vendor); - } - if (model) { - writeComment(" " + localize("model") + ": " + model); - } - if (description) { - writeComment(" " + localize("description") + ": " + description); - } - } - - // dump tool information - if (properties.writeTools) { - var zRanges = {}; - if (is3D()) { - var numberOfSections = getNumberOfSections(); - for (var i = 0; i < numberOfSections; ++i) { - var section = getSection(i); - var zRange = section.getGlobalZRange(); - var tool = section.getTool(); - if (zRanges[tool.number]) { - zRanges[tool.number].expandToRange(zRange); - } else { - zRanges[tool.number] = zRange; - } - } - } - - var tools = getToolTable(); - if (tools.getNumberOfTools() > 0) { - for (var i = 0; i < tools.getNumberOfTools(); ++i) { - var tool = tools.getTool(i); - var comment = "T" + toolFormat.format(tool.number) + " " + - "D=" + xyzFormat.format(tool.diameter) + " " + - localize("CR") + "=" + xyzFormat.format(tool.cornerRadius); - if ((tool.taperAngle > 0) && (tool.taperAngle < Math.PI)) { - comment += " " + localize("TAPER") + "=" + taperFormat.format(tool.taperAngle) + localize("deg"); - } - if (zRanges[tool.number]) { - comment += " - " + localize("ZMIN") + "=" + xyzFormat.format(zRanges[tool.number].getMinimum()); - } - comment += " - " + getToolTypeName(tool.type); - writeComment(comment); - } - } - } - - // optionally cycle through all tools - if (properties.optionallyCycleToolsAtStart || properties.optionallyMeasureToolsAtStart) { - var tools = getToolTable(); - if (tools.getNumberOfTools() > 0) { - writeln(""); - - writeOptionalBlock(mFormat.format(0), formatComment(localize("Read note"))); // wait for operator - writeComment(localize("With BLOCK DELETE turned off each tool will cycle through")); - writeComment(localize("the spindle to verify that the correct tool is in the tool magazine")); - if (properties.optionallyMeasureToolsAtStart) { - writeComment(localize("and to automatically measure it")); - } - writeComment(localize("Once the tools are verified turn BLOCK DELETE on to skip verification")); - - for (var i = 0; i < tools.getNumberOfTools(); ++i) { - var tool = tools.getTool(i); - if (properties.optionallyMeasureToolsAtStart && (tool.type == TOOL_PROBE)) { - continue; - } - var comment = "T" + toolFormat.format(tool.number) + " " + - "D=" + xyzFormat.format(tool.diameter) + " " + - localize("CR") + "=" + xyzFormat.format(tool.cornerRadius); - if ((tool.taperAngle > 0) && (tool.taperAngle < Math.PI)) { - comment += " " + localize("TAPER") + "=" + taperFormat.format(tool.taperAngle) + localize("deg"); - } - comment += " - " + getToolTypeName(tool.type); - writeComment(comment); - if (properties.optionallyMeasureToolsAtStart) { - writeOptionalBlock("T" + toolFormat.format(tool.number), mFormat.format(6)); //Changes Tool - writeOptionalBlock(mFormat.format(0), formatComment(localize("Load Tool"))); //Pause until operator loads tool - writeToolMeasureBlock(tool); - } else { - writeToolCycleBlock(tool); - } - } - writeOptionalBlock(mFormat.format(0), formatComment(localize("Operator Start Program"))); // wait for operator - } - writeln(""); - } - - if (false /*properties.useDWO*/) { - var failed = false; - var dynamicWCSs = {}; - for (var i = 0; i < getNumberOfSections(); ++i) { - var section = getSection(i); - var description = section.hasParameter("operation-comment") ? section.getParameter("operation-comment") : ("#" + (i + 1)); - if (!section.hasDynamicWorkOffset()) { - error(subst(localize("Dynamic work offset has not been set for operation '%1'."), description)); - failed = true; - } - - var o = section.getDynamicWCSOrigin(); - var p = section.getDynamicWCSPlane(); - if (dynamicWCSs[section.getDynamicWorkOffset()]) { - if ((Vector.diff(o, dynamicWCSs[section.getDynamicWorkOffset()].origin).length > 1e-9) || - (Matrix.diff(p, dynamicWCSs[section.getDynamicWorkOffset()].plane).n1 > 1e-9)) { - error(subst(localize("Dynamic WCS mismatch for operation '%1'."), description)); - failed = true; - } - } else { - dynamicWCSs[section.getDynamicWorkOffset()] = {origin:o, plane:p}; - } - } - if (failed) { - return; - } - } - - if (false) { - // check for duplicate tool number - for (var i = 0; i < getNumberOfSections(); ++i) { - var sectioni = getSection(i); - var tooli = sectioni.getTool(); - for (var j = i + 1; j < getNumberOfSections(); ++j) { - var sectionj = getSection(j); - var toolj = sectionj.getTool(); - if (tooli.number == toolj.number) { - if (xyzFormat.areDifferent(tooli.diameter, toolj.diameter) || - xyzFormat.areDifferent(tooli.cornerRadius, toolj.cornerRadius) || - abcFormat.areDifferent(tooli.taperAngle, toolj.taperAngle) || - (tooli.numberOfFlutes != toolj.numberOfFlutes)) { - error( - subst( - localize("Using the same tool number for different cutter geometry for operation '%1' and '%2'."), - sectioni.hasParameter("operation-comment") ? sectioni.getParameter("operation-comment") : ("#" + (i + 1)), - sectionj.hasParameter("operation-comment") ? sectionj.getParameter("operation-comment") : ("#" + (j + 1)) - ) - ); - return; - } - } - } - } - } - - if ((getNumberOfSections() > 0) && (getSection(0).workOffset == 0)) { - for (var i = 0; i < getNumberOfSections(); ++i) { - if (getSection(i).workOffset > 0) { - error(localize("Using multiple work offsets is not possible if the initial work offset is 0.")); - return; - } - } - } - - // absolute coordinates and feed per min - writeBlock(gAbsIncModal.format(90), gFeedModeModal.format(94), gPlaneModal.format(17)); - - switch (unit) { - case IN: - writeBlock(gUnitModal.format(20)); - break; - case MM: - writeBlock(gUnitModal.format(21)); - break; - } - - if (properties.chipTransport) { - onCommand(COMMAND_START_CHIP_TRANSPORT); - } - // Probing Surface Inspection - if (typeof inspectionWriteVariables == "function") { - inspectionWriteVariables(); - } -} - -function onComment(message) { - writeComment(message); -} - -/** Force output of X, Y, and Z. */ -function forceXYZ() { - xOutput.reset(); - yOutput.reset(); - zOutput.reset(); -} - -/** Force output of A, B, and C. */ -function forceABC() { - aOutput.reset(); - bOutput.reset(); - cOutput.reset(); -} - -function forceFeed() { - currentFeedId = undefined; - feedOutput.reset(); -} - -/** Force output of X, Y, Z, A, B, C, and F on next output. */ -function forceAny() { - forceXYZ(); - forceABC(); - forceFeed(); -} - -function writeG187() { - if (hasParameter("operation-strategy") && (getParameter("operation-strategy") == "drill")) { - writeBlock(gFormat.format(187)); // reset G187 setting to machine default - } else if (hasParameter("operation:tolerance")) { - var tolerance = Math.max(getParameter("operation:tolerance"), 0); - if (tolerance > 0) { - var stockToLeaveThreshold = toUnit(0.1, MM); - var stockToLeave = 0; - var verticalStockToLeave = 0; - if (hasParameter("operation:stockToLeave")) { - stockToLeave = xyzFormat.getResultingValue(getParameter("operation:stockToLeave")); - } - if (hasParameter("operation:verticalStockToLeave")) { - verticalStockToLeave = xyzFormat.getResultingValue(getParameter("operation:verticalStockToLeave")); - } - - var workMode; - if (((stockToLeave > stockToLeaveThreshold) && (verticalStockToLeave > stockToLeaveThreshold)) || - (hasParameter("operation:strategy") && getParameter("operation:strategy") == "face")) { - workMode = 1; // roughing - } else { - if ((stockToLeave > 0) || (verticalStockToLeave > 0)) { - workMode = 2; // default - } else { - workMode = 3; // fine - } - } - writeBlock(gFormat.format(187), "P" + workMode); // set tolerance mode - // writeBlock(gFormat.format(187), "P" + workMode, "E" + xyzFormat.format(tolerance)); // set tolerance mode - } else { - writeBlock(gFormat.format(187)); // reset G187 setting to machine default - } - } else { - writeBlock(gFormat.format(187)); // reset G187 setting to machine default - } -} - -function FeedContext(id, description, feed) { - this.id = id; - this.description = description; - this.feed = feed; -} - -function getFeed(f) { - if (activeMovements) { - var feedContext = activeMovements[movement]; - if (feedContext != undefined) { - if (!feedFormat.areDifferent(feedContext.feed, f)) { - if (feedContext.id == currentFeedId) { - return ""; // nothing has changed - } - forceFeed(); - currentFeedId = feedContext.id; - return "F#" + (firstFeedParameter + feedContext.id); - } - } - currentFeedId = undefined; // force Q feed next time - } - return feedOutput.format(f); // use feed value -} - -function initializeActiveFeeds() { - activeMovements = new Array(); - var movements = currentSection.getMovements(); - - var id = 0; - var activeFeeds = new Array(); - if (hasParameter("operation:tool_feedCutting")) { - if (movements & ((1 << MOVEMENT_CUTTING) | (1 << MOVEMENT_LINK_TRANSITION) | (1 << MOVEMENT_EXTENDED))) { - var feedContext = new FeedContext(id, localize("Cutting"), getParameter("operation:tool_feedCutting")); - activeFeeds.push(feedContext); - activeMovements[MOVEMENT_CUTTING] = feedContext; - activeMovements[MOVEMENT_LINK_TRANSITION] = feedContext; - activeMovements[MOVEMENT_EXTENDED] = feedContext; - } - ++id; - if (movements & (1 << MOVEMENT_PREDRILL)) { - feedContext = new FeedContext(id, localize("Predrilling"), getParameter("operation:tool_feedCutting")); - activeMovements[MOVEMENT_PREDRILL] = feedContext; - activeFeeds.push(feedContext); - } - ++id; - } - - if (hasParameter("operation:finishFeedrate")) { - if (movements & (1 << MOVEMENT_FINISH_CUTTING)) { - var feedContext = new FeedContext(id, localize("Finish"), getParameter("operation:finishFeedrate")); - activeFeeds.push(feedContext); - activeMovements[MOVEMENT_FINISH_CUTTING] = feedContext; - } - ++id; - } else if (hasParameter("operation:tool_feedCutting")) { - if (movements & (1 << MOVEMENT_FINISH_CUTTING)) { - var feedContext = new FeedContext(id, localize("Finish"), getParameter("operation:tool_feedCutting")); - activeFeeds.push(feedContext); - activeMovements[MOVEMENT_FINISH_CUTTING] = feedContext; - } - ++id; - } - - if (hasParameter("operation:tool_feedEntry")) { - if (movements & (1 << MOVEMENT_LEAD_IN)) { - var feedContext = new FeedContext(id, localize("Entry"), getParameter("operation:tool_feedEntry")); - activeFeeds.push(feedContext); - activeMovements[MOVEMENT_LEAD_IN] = feedContext; - } - ++id; - } - - if (hasParameter("operation:tool_feedExit")) { - if (movements & (1 << MOVEMENT_LEAD_OUT)) { - var feedContext = new FeedContext(id, localize("Exit"), getParameter("operation:tool_feedExit")); - activeFeeds.push(feedContext); - activeMovements[MOVEMENT_LEAD_OUT] = feedContext; - } - ++id; - } - - if (hasParameter("operation:noEngagementFeedrate")) { - if (movements & (1 << MOVEMENT_LINK_DIRECT)) { - var feedContext = new FeedContext(id, localize("Direct"), getParameter("operation:noEngagementFeedrate")); - activeFeeds.push(feedContext); - activeMovements[MOVEMENT_LINK_DIRECT] = feedContext; - } - ++id; - } else if (hasParameter("operation:tool_feedCutting") && - hasParameter("operation:tool_feedEntry") && - hasParameter("operation:tool_feedExit")) { - if (movements & (1 << MOVEMENT_LINK_DIRECT)) { - var feedContext = new FeedContext(id, localize("Direct"), Math.max(getParameter("operation:tool_feedCutting"), getParameter("operation:tool_feedEntry"), getParameter("operation:tool_feedExit"))); - activeFeeds.push(feedContext); - activeMovements[MOVEMENT_LINK_DIRECT] = feedContext; - } - ++id; - } - - if (hasParameter("operation:reducedFeedrate")) { - if (movements & (1 << MOVEMENT_REDUCED)) { - var feedContext = new FeedContext(id, localize("Reduced"), getParameter("operation:reducedFeedrate")); - activeFeeds.push(feedContext); - activeMovements[MOVEMENT_REDUCED] = feedContext; - } - ++id; - } - - if (hasParameter("operation:tool_feedRamp")) { - if (movements & ((1 << MOVEMENT_RAMP) | (1 << MOVEMENT_RAMP_HELIX) | (1 << MOVEMENT_RAMP_PROFILE) | (1 << MOVEMENT_RAMP_ZIG_ZAG))) { - var feedContext = new FeedContext(id, localize("Ramping"), getParameter("operation:tool_feedRamp")); - activeFeeds.push(feedContext); - activeMovements[MOVEMENT_RAMP] = feedContext; - activeMovements[MOVEMENT_RAMP_HELIX] = feedContext; - activeMovements[MOVEMENT_RAMP_PROFILE] = feedContext; - activeMovements[MOVEMENT_RAMP_ZIG_ZAG] = feedContext; - } - ++id; - } - if (hasParameter("operation:tool_feedPlunge")) { - if (movements & (1 << MOVEMENT_PLUNGE)) { - var feedContext = new FeedContext(id, localize("Plunge"), getParameter("operation:tool_feedPlunge")); - activeFeeds.push(feedContext); - activeMovements[MOVEMENT_PLUNGE] = feedContext; - } - ++id; - } - if (true) { // high feed - if (movements & (1 << MOVEMENT_HIGH_FEED)) { - var feedContext = new FeedContext(id, localize("High Feed"), this.highFeedrate); - activeFeeds.push(feedContext); - activeMovements[MOVEMENT_HIGH_FEED] = feedContext; - } - ++id; - } - - for (var i = 0; i < activeFeeds.length; ++i) { - var feedContext = activeFeeds[i]; - writeBlock("#" + (firstFeedParameter + feedContext.id) + "=" + feedFormat.format(feedContext.feed), formatComment(feedContext.description)); - } -} - -var currentWorkPlaneABC = undefined; -var activeG254 = false; - -function forceWorkPlane() { - currentWorkPlaneABC = undefined; -} - -function defineWorkPlane(_section, _setWorkPlane) { - var abc = new Vector(0, 0, 0); - if (machineConfiguration.isMultiAxisConfiguration()) { // use 5-axis indexing for multi-axis mode - // set working plane after datum shift - - if (_section.isMultiAxis()) { - cancelTransformation(); - abc = _section.getInitialToolAxisABC(); - if (_setWorkPlane) { - if (activeG254) { - writeBlock(gFormat.format(255)); // cancel DWO - activeG254 = false; - } - if (!retracted) { - writeRetract(Z); - } - forceWorkPlane(); - onCommand(COMMAND_UNLOCK_MULTI_AXIS); - gMotionModal.reset(); - writeBlock( - gMotionModal.format(0), - conditional(machineConfiguration.isMachineCoordinate(0), "A" + abcFormat.format(abc.x)), - conditional(machineConfiguration.isMachineCoordinate(1), "B" + abcFormat.format(abc.y)), - conditional(machineConfiguration.isMachineCoordinate(2), "C" + abcFormat.format(abc.z)) - ); - } - } else { - abc = getWorkPlaneMachineABC(_section.workPlane, _setWorkPlane); - if (_setWorkPlane) { - setWorkPlane(abc); - } - } - } else { // pure 3D - var remaining = _section.workPlane; - if (!isSameDirection(remaining.forward, new Vector(0, 0, 1))) { - error(localize("Tool orientation is not supported.")); - return abc; - } - setRotation(remaining); - } - return abc; -} - -function setWorkPlane(abc) { - if (!machineConfiguration.isMultiAxisConfiguration()) { - return; // ignore - } - - if (!((currentWorkPlaneABC == undefined) || - abcFormat.areDifferent(abc.x, currentWorkPlaneABC.x) || - abcFormat.areDifferent(abc.y, currentWorkPlaneABC.y) || - abcFormat.areDifferent(abc.z, currentWorkPlaneABC.z))) { - return; // no change - } - - onCommand(COMMAND_UNLOCK_MULTI_AXIS); - - if (activeG254) { - writeBlock(operationNeedsSafeWorkPlane ? "/" : "", gFormat.format(255)); // cancel DWO - activeG254 = false; - } - - gMotionModal.reset(); - writeBlock( - operationNeedsSafeWorkPlane ? "/" : "", - gMotionModal.format(0), - conditional(machineConfiguration.isMachineCoordinate(0), "A" + abcFormat.format(abc.x)), - conditional(machineConfiguration.isMachineCoordinate(1), "B" + abcFormat.format(abc.y)), - conditional(machineConfiguration.isMachineCoordinate(2), "C" + abcFormat.format(abc.z)) - ); - - onCommand(COMMAND_LOCK_MULTI_AXIS); - - if (properties.useDWO && - (abcFormat.isSignificant(abc.x) || abcFormat.isSignificant(abc.y) || abcFormat.isSignificant(abc.z))) { - writeBlock(operationNeedsSafeWorkPlane ? "/" : "", gFormat.format(254)); // enable DWO - activeG254 = true; - } - - currentWorkPlaneABC = abc; -} - -var closestABC = false; // choose closest machine angles -var currentMachineABC; - -function getWorkPlaneMachineABC(workPlane, _setWorkPlane) { - var W = workPlane; // map to global frame - - var abc = machineConfiguration.getABC(W); - if (closestABC) { - if (currentMachineABC) { - abc = machineConfiguration.remapToABC(abc, currentMachineABC); - } else { - abc = machineConfiguration.getPreferredABC(abc); - } - } else { - abc = machineConfiguration.getPreferredABC(abc); - } - - try { - abc = machineConfiguration.remapABC(abc); - if (_setWorkPlane) { - currentMachineABC = abc; - } - } catch (e) { - error( - localize("Machine angles not supported") + ":" - + conditional(machineConfiguration.isMachineCoordinate(0), " A" + abcFormat.format(abc.x)) - + conditional(machineConfiguration.isMachineCoordinate(1), " B" + abcFormat.format(abc.y)) - + conditional(machineConfiguration.isMachineCoordinate(2), " C" + abcFormat.format(abc.z)) - ); - } - - var direction = machineConfiguration.getDirection(abc); - if (!isSameDirection(direction, W.forward)) { - error(localize("Orientation not supported.")); - } - - if (!machineConfiguration.isABCSupported(abc)) { - error( - localize("Work plane is not supported") + ":" - + conditional(machineConfiguration.isMachineCoordinate(0), " A" + abcFormat.format(abc.x)) - + conditional(machineConfiguration.isMachineCoordinate(1), " B" + abcFormat.format(abc.y)) - + conditional(machineConfiguration.isMachineCoordinate(2), " C" + abcFormat.format(abc.z)) - ); - } - - var tcp = false; - if (tcp) { - setRotation(W); // TCP mode - } else { - var O = machineConfiguration.getOrientation(abc); - var R = machineConfiguration.getRemainingOrientation(abc, W); - setRotation(R); - } - - return abc; -} - -function isProbeOperation() { - return hasParameter("operation-strategy") && ((getParameter("operation-strategy") == "probe" || getParameter("operation-strategy") == "probe_geometry")); -} - -function isInspectionOperation(section) { - return section.hasParameter("operation-strategy") && (section.getParameter("operation-strategy") == "inspectSurface"); -} - -var probeOutputWorkOffset = 1; - -function onPassThrough(text) { - var commands = String(text).split(","); - for (text in commands) { - writeBlock(commands[text]); - } -} - -function onParameter(name, value) { - if (name == "probe-output-work-offset") { - probeOutputWorkOffset = (value > 0) ? value : 1; - } -} - -/** Returns true if the spatial vectors are significantly different. */ -function areSpatialVectorsDifferent(_vector1, _vector2) { - return (xyzFormat.getResultingValue(_vector1.x) != xyzFormat.getResultingValue(_vector2.x)) || - (xyzFormat.getResultingValue(_vector1.y) != xyzFormat.getResultingValue(_vector2.y)) || - (xyzFormat.getResultingValue(_vector1.z) != xyzFormat.getResultingValue(_vector2.z)); -} - -/** Returns true if the spatial boxes are a pure translation. */ -function areSpatialBoxesTranslated(_box1, _box2) { - return !areSpatialVectorsDifferent(Vector.diff(_box1[1], _box1[0]), Vector.diff(_box2[1], _box2[0])) && - !areSpatialVectorsDifferent(Vector.diff(_box2[0], _box1[0]), Vector.diff(_box2[1], _box1[1])); -} - -/** Returns true if the spatial boxes are same. */ -function areSpatialBoxesSame(_box1, _box2) { - return !areSpatialVectorsDifferent(_box1[0], _box2[0]) && !areSpatialVectorsDifferent(_box1[1], _box2[1]); -} - -function subprogramDefine(_initialPosition, _abc, _retracted, _zIsOutput) { - // convert patterns into subprograms - var usePattern = false; - patternIsActive = false; - if (currentSection.isPatterned && currentSection.isPatterned() && properties.useSubroutinePatterns) { - currentPattern = currentSection.getPatternId(); - firstPattern = true; - for (var i = 0; i < definedPatterns.length; ++i) { - if ((definedPatterns[i].patternType == SUB_PATTERN) && (currentPattern == definedPatterns[i].patternId)) { - currentSubprogram = definedPatterns[i].subProgram; - usePattern = definedPatterns[i].validPattern; - firstPattern = false; - break; - } - } - - if (firstPattern) { - // determine if this is a valid pattern for creating a subprogram - usePattern = subprogramIsValid(currentSection, currentPattern, SUB_PATTERN); - if (usePattern) { - currentSubprogram = ++lastSubprogram; - } - definedPatterns.push({ - patternType: SUB_PATTERN, - patternId: currentPattern, - subProgram: currentSubprogram, - validPattern: usePattern, - initialPosition: _initialPosition, - finalPosition: _initialPosition - }); - } - - if (usePattern) { - // make sure Z-position is output prior to subprogram call - if (!_retracted && !_zIsOutput) { - writeBlock(gMotionModal.format(0), zOutput.format(_initialPosition.z)); - } - - // call subprogram - writeBlock(mFormat.format(97), "P" + nFormat.format(currentSubprogram)); - patternIsActive = true; - - if (firstPattern) { - subprogramStart(_initialPosition, _abc, incrementalSubprogram); - } else { - skipRemainingSection(); - setCurrentPosition(getFramePosition(currentSection.getFinalPosition())); - } - } - } - - // Output cycle operation as subprogram - if (!usePattern && properties.useSubroutineCycles && currentSection.doesStrictCycle && - (currentSection.getNumberOfCycles() == 1) && currentSection.getNumberOfCyclePoints() >= minimumCyclePoints) { - var finalPosition = getFramePosition(currentSection.getFinalPosition()); - currentPattern = currentSection.getNumberOfCyclePoints(); - firstPattern = true; - for (var i = 0; i < definedPatterns.length; ++i) { - if ((definedPatterns[i].patternType == SUB_CYCLE) && (currentPattern == definedPatterns[i].patternId) && - !areSpatialVectorsDifferent(_initialPosition, definedPatterns[i].initialPosition) && - !areSpatialVectorsDifferent(finalPosition, definedPatterns[i].finalPosition)) { - currentSubprogram = definedPatterns[i].subProgram; - usePattern = definedPatterns[i].validPattern; - firstPattern = false; - break; - } - } - - if (firstPattern) { - // determine if this is a valid pattern for creating a subprogram - usePattern = subprogramIsValid(currentSection, currentPattern, SUB_CYCLE); - if (usePattern) { - currentSubprogram = ++lastSubprogram; - } - definedPatterns.push({ - patternType: SUB_CYCLE, - patternId: currentPattern, - subProgram: currentSubprogram, - validPattern: usePattern, - initialPosition: _initialPosition, - finalPosition: finalPosition - }); - } - cycleSubprogramIsActive = usePattern; - } - - // Output each operation as a subprogram - if (!usePattern && properties.useSubroutines) { - currentSubprogram = ++lastSubprogram; - writeBlock(mFormat.format(97), "P" + nFormat.format(currentSubprogram)); - firstPattern = true; - subprogramStart(_initialPosition, _abc, false); - } -} - -function subprogramStart(_initialPosition, _abc, _incremental) { - redirectToBuffer(); - var comment = ""; - if (hasParameter("operation-comment")) { - comment = getParameter("operation-comment"); - } - writeln( - "N" + nFormat.format(currentSubprogram) + - conditional(comment, formatComment(comment.substr(0, maximumLineLength - 2 - 6 - 1))) - ); - saveShowSequenceNumbers = properties.showSequenceNumbers; - properties.showSequenceNumbers = false; - if (_incremental) { - setIncrementalMode(_initialPosition, _abc); - } - gPlaneModal.reset(); - gMotionModal.reset(); -} - -function subprogramEnd() { - if (firstPattern) { - writeBlock(mFormat.format(99)); - writeln(""); - subprograms += getRedirectionBuffer(); - } - forceAny(); - firstPattern = false; - properties.showSequenceNumbers = saveShowSequenceNumbers; - closeRedirection(); -} - -function subprogramIsValid(_section, _patternId, _patternType) { - var sectionId = _section.getId(); - var numberOfSections = getNumberOfSections(); - var validSubprogram = _patternType != SUB_CYCLE; - - var masterPosition = new Array(); - masterPosition[0] = getFramePosition(_section.getInitialPosition()); - masterPosition[1] = getFramePosition(_section.getFinalPosition()); - var tempBox = _section.getBoundingBox(); - var masterBox = new Array(); - masterBox[0] = getFramePosition(tempBox[0]); - masterBox[1] = getFramePosition(tempBox[1]); - - var rotation = getRotation(); - var translation = getTranslation(); - incrementalSubprogram = undefined; - - for (var i = 0; i < numberOfSections; ++i) { - var section = getSection(i); - if (section.getId() != sectionId) { - defineWorkPlane(section, false); - // check for valid pattern - if (_patternType == SUB_PATTERN) { - if (section.getPatternId() == _patternId) { - var patternPosition = new Array(); - patternPosition[0] = getFramePosition(section.getInitialPosition()); - patternPosition[1] = getFramePosition(section.getFinalPosition()); - tempBox = section.getBoundingBox(); - var patternBox = new Array(); - patternBox[0] = getFramePosition(tempBox[0]); - patternBox[1] = getFramePosition(tempBox[1]); - - if (areSpatialBoxesSame(masterPosition, patternPosition) && areSpatialBoxesSame(masterBox, patternBox)) { - incrementalSubprogram = incrementalSubprogram ? incrementalSubprogram : false; - } else if (!areSpatialBoxesTranslated(masterPosition, patternPosition) || !areSpatialBoxesTranslated(masterBox, patternBox)) { - validSubprogram = false; - break; - } else { - incrementalSubprogram = true; - } - } - - // check for valid cycle operation - } else if (_patternType == SUB_CYCLE) { - if ((section.getNumberOfCyclePoints() == _patternId) && (section.getNumberOfCycles() == 1)) { - var patternInitial = getFramePosition(section.getInitialPosition()); - var patternFinal = getFramePosition(section.getFinalPosition()); - if (!areSpatialVectorsDifferent(patternInitial, masterPosition[0]) && !areSpatialVectorsDifferent(patternFinal, masterPosition[1])) { - validSubprogram = true; - break; - } - } - } - } - } - setRotation(rotation); - setTranslation(translation); - return (validSubprogram); -} - -function setAxisMode(_format, _output, _prefix, _value, _incr) { - var i = _output.isEnabled(); - _output = _incr ? createIncrementalVariable({prefix: _prefix}, _format) : createVariable({prefix: _prefix}, _format); - _output.format(_value); - _output.format(_value); - i = i ? _output.enable() : _output.disable(); - return _output; -} - -function setIncrementalMode(xyz, abc) { - xOutput = setAxisMode(xyzFormat, xOutput, "X", xyz.x, true); - yOutput = setAxisMode(xyzFormat, yOutput, "Y", xyz.y, true); - zOutput = setAxisMode(xyzFormat, zOutput, "Z", xyz.z, true); - aOutput = setAxisMode(abcFormat, aOutput, "A", abc.x, true); - bOutput = setAxisMode(abcFormat, bOutput, "B", abc.y, true); - cOutput = setAxisMode(abcFormat, cOutput, "C", abc.z, true); - gAbsIncModal.reset(); - writeBlock(gAbsIncModal.format(91)); - incrementalMode = true; -} - -function setAbsoluteMode(xyz, abc) { - if (incrementalMode) { - xOutput = setAxisMode(xyzFormat, xOutput, "X", xyz.x, false); - yOutput = setAxisMode(xyzFormat, yOutput, "Y", xyz.y, false); - zOutput = setAxisMode(xyzFormat, zOutput, "Z", xyz.z, false); - aOutput = setAxisMode(abcFormat, aOutput, "A", abc.x, false); - bOutput = setAxisMode(abcFormat, bOutput, "B", abc.y, false); - cOutput = setAxisMode(abcFormat, cOutput, "C", abc.z, false); - gAbsIncModal.reset(); - writeBlock(gAbsIncModal.format(90)); - incrementalMode = false; - } -} - -function onSection() { - var forceToolAndRetract = optionalSection && !currentSection.isOptional(); - optionalSection = currentSection.isOptional(); - - var insertToolCall = isFirstSection() || - currentSection.getForceToolChange && currentSection.getForceToolChange() || - (tool.number != getPreviousSection().getTool().number); - - retracted = false; - - var zIsOutput = false; // true if the Z-position has been output, used for patterns - var newWorkOffset = isFirstSection() || - (getPreviousSection().workOffset != currentSection.workOffset); // work offset changes - var newWorkPlane = isFirstSection() || - !isSameDirection(getPreviousSection().getGlobalFinalToolAxis(), currentSection.getGlobalInitialToolAxis()) || - (currentSection.isOptimizedForMachine() && getPreviousSection().isOptimizedForMachine() && - Vector.diff(getPreviousSection().getFinalToolAxisABC(), currentSection.getInitialToolAxisABC()).length > 1e-4) || - (!machineConfiguration.isMultiAxisConfiguration() && currentSection.isMultiAxis()) || - (!getPreviousSection().isMultiAxis() && currentSection.isMultiAxis() || - getPreviousSection().isMultiAxis() && !currentSection.isMultiAxis()); // force newWorkPlane between indexing and simultaneous operations - - if (properties.safeStartAllOperations && !isFirstSection()) { // determine what needs to be included in safe start - if (!insertToolCall) { // tool call required - operationNeedsSafeToolCall = true; - forceSpindleSpeed = true; - } - if (!newWorkOffset) { // offset required - operationNeedsSafeWorkOffset = true; - } - if (!newWorkPlane) { // workplane required - operationNeedsSafeWorkPlane = true; - } - operationNeedsSafeStart = true; // operation will contain safe start components - } - - if ((insertToolCall && !properties.fastToolChange) || newWorkOffset || newWorkPlane || toolChecked) { - - // stop spindle before retract during tool change - if (insertToolCall && !isFirstSection() && !toolChecked && !properties.fastToolChange) { - onCommand(COMMAND_STOP_SPINDLE); - } - - // retract to safe plane - writeRetract(Z); - - if (forceResetWorkPlane && newWorkPlane) { - forceWorkPlane(); - setWorkPlane(new Vector(0, 0, 0)); // reset working plane - } - } - - if (hasParameter("operation-comment")) { - var comment = getParameter("operation-comment"); - if (comment && ((comment !== lastOperationComment) || !patternIsActive || insertToolCall)) { - writeln(""); - writeComment(comment); - lastOperationComment = comment; - } else if (!patternIsActive || insertToolCall) { - writeln(""); - } - } else { - writeln(""); - } - - if (operationNeedsSafeStart && !retracted) { // retract before safestart operations - skipBlock = true; - writeRetract(Z); - } - - if (properties.showNotes && hasParameter("notes")) { - var notes = getParameter("notes"); - if (notes) { - var lines = String(notes).split("\n"); - var r1 = new RegExp("^[\\s]+", "g"); - var r2 = new RegExp("[\\s]+$", "g"); - for (line in lines) { - var comment = lines[line].replace(r1, "").replace(r2, ""); - if (comment) { - writeComment(comment); - } - } - } - } - - if (insertToolCall || operationNeedsSafeStart) { - forceWorkPlane(); - - if (properties.fastToolChange && !isProbeOperation()) { - currentCoolantMode = COOLANT_OFF; - } else if (!operationNeedsSafeToolCall) { // no coolant off command if safe start operation - onCommand(COMMAND_COOLANT_OFF); - } - - if (!isFirstSection() && properties.optionalStop) { - onCommand(COMMAND_OPTIONAL_STOP); - } - - if ((tool.number > 200 && tool.number < 1000) || tool.number > 9999) { - warning(localize("Tool number out of range.")); - } - - skipBlock = operationNeedsSafeToolCall; - writeToolBlock( - "T" + toolFormat.format(tool.number), - mFormat.format(6) - ); - if (tool.comment) { - writeComment(tool.comment); - } - if (measureTool) { - writeToolMeasureBlock(tool); - } - var showToolZMin = false; - if (showToolZMin) { - if (is3D()) { - var numberOfSections = getNumberOfSections(); - var zRange = currentSection.getGlobalZRange(); - var number = tool.number; - for (var i = currentSection.getId() + 1; i < numberOfSections; ++i) { - var section = getSection(i); - if (section.getTool().number != number) { - break; - } - zRange.expandToRange(section.getGlobalZRange()); - } - writeComment(localize("ZMIN") + "=" + xyzFormat.format(zRange.getMinimum())); - } - } - } - - // activate those two coolant modes before the spindle is turned on - if ((tool.coolant == COOLANT_THROUGH_TOOL) || (tool.coolant == COOLANT_AIR_THROUGH_TOOL) || (tool.coolant == COOLANT_FLOOD_THROUGH_TOOL)) { - if (!isFirstSection() && !insertToolCall && (currentCoolantMode != tool.coolant)) { - onCommand(COMMAND_STOP_SPINDLE); - forceSpindleSpeed = true; - } - setCoolant(tool.coolant); - } else if ((currentCoolantMode == COOLANT_THROUGH_TOOL) || (currentCoolantMode == COOLANT_AIR_THROUGH_TOOL) || (currentCoolantMode == COOLANT_FLOOD_THROUGH_TOOL)) { - onCommand(COMMAND_STOP_SPINDLE); - setCoolant(COOLANT_OFF); - forceSpindleSpeed = true; - } - - if (toolChecked) { - forceSpindleSpeed = true; // spindle must be restarted if tool is checked without a tool change - toolChecked = false; // state of tool is not known at the beginning of a section since it could be broken for the previous section - } - - if (!isInspectionOperation(currentSection) && !isProbeOperation() && - (insertToolCall || - forceSpindleSpeed || - isFirstSection() || - (rpmFormat.areDifferent(spindleSpeed, sOutput.getCurrent())) || - (tool.clockwise != getPreviousSection().getTool().clockwise))) { - forceSpindleSpeed = false; - - if (spindleSpeed < 1) { - error(localize("Spindle speed out of range.")); - return; - } - if (spindleSpeed > 15000) { - warning(localize("Spindle speed exceeds maximum value.")); - } - writeBlock( - sOutput.format(spindleSpeed), mFormat.format(tool.clockwise ? 3 : 4) - ); - } - - if (properties.useParametricFeed && - hasParameter("operation-strategy") && - (getParameter("operation-strategy") != "drill") && // legacy - !(currentSection.hasAnyCycle && currentSection.hasAnyCycle())) { - if (!insertToolCall && - activeMovements && - (getCurrentSectionId() > 0) && - ((getPreviousSection().getPatternId() == currentSection.getPatternId()) && (currentSection.getPatternId() != 0))) { - // use the current feeds - } else { - initializeActiveFeeds(); - } - } else { - activeMovements = undefined; - } - - // wcs - if (insertToolCall || operationNeedsSafeWorkOffset) { // force work offset when changing tool - currentWorkOffset = undefined; - } - var workOffset = currentSection.workOffset; - if (workOffset == 0) { - warningOnce(localize("Work offset has not been specified. Using G54 as WCS."), WARNING_WORK_OFFSET); - workOffset = 1; - } - if (workOffset > 0) { - if (workOffset > 6) { - var code = workOffset - 6; - if (code > 99) { - error(localize("Work offset out of range.")); - return; - } - if (workOffset != currentWorkOffset) { - forceWorkPlane(); - writeBlock(gFormat.format(154), "P" + code); - currentWorkOffset = workOffset; - } - } else { - if (workOffset != currentWorkOffset) { - forceWorkPlane(); - writeBlock(gFormat.format(53 + workOffset)); // G54->G59 - currentWorkOffset = workOffset; - } - } - } - - if (newWorkPlane || (insertToolCall && !retracted)) { // go to home position for safety - if (!retracted) { - writeRetract(Z); - } - } - - forceXYZ(); - - // Unwind axis if previous section was Multi-Axis - if (!isFirstSection() && getPreviousSection().isMultiAxis() && hasC) { - writeBlock(gFormat.format(28), gAbsIncModal.format(91), "C" + abcFormat.format(0)); - writeBlock(gAbsIncModal.format(90)); - } - - if (newWorkOffset) { - forceWorkPlane(); - } - - var abc = defineWorkPlane(currentSection, true); - - // set coolant after we have positioned at Z - setCoolant(tool.coolant); - - forceAny(); - gMotionModal.reset(); - - if (properties.useG187) { - writeG187(); - } - - var initialPosition = getFramePosition(currentSection.getInitialPosition()); - if (!retracted && !insertToolCall) { - if (getCurrentPosition().z < initialPosition.z) { - writeBlock(gMotionModal.format(0), zOutput.format(initialPosition.z)); - zIsOutput = true; - } - } - - if (insertToolCall || retracted || operationNeedsSafeStart || - (!isFirstSection() && (currentSection.isMultiAxis() != getPreviousSection().isMultiAxis()))) { - var lengthOffset = tool.lengthOffset; - if ((lengthOffset > 200 && lengthOffset < 1000) || lengthOffset > 9999) { - error(localize("Length offset out of range.")); - return; - } - - gMotionModal.reset(); - writeBlock(gPlaneModal.format(17)); - - if (!machineConfiguration.isHeadConfiguration()) { - if ((currentSection.getOptimizedTCPMode() == 0) && useDwoForPositioning && currentSection.isMultiAxis()) { - var O = machineConfiguration.getOrientation(abc); - var initialPositionDWO = O.getTransposed().multiply(getGlobalPosition(currentSection.getInitialPosition())); - // writeComment("PREPOSITIONING START"); - writeBlock(gFormat.format(254)); - writeBlock(gAbsIncModal.format(90), gMotionModal.format(0), xOutput.format(initialPositionDWO.x), yOutput.format(initialPositionDWO.y)); - writeBlock(gFormat.format(255)); - // writeComment("PREPOSITIONING END"); - writeBlock( - gMotionModal.format(0), - conditional(!currentSection.isMultiAxis() || (currentSection.getOptimizedTCPMode() == 1), gFormat.format(43)), - conditional(currentSection.isMultiAxis() && (currentSection.getOptimizedTCPMode() == 0), gFormat.format(234)), - xOutput.format(initialPosition.x), yOutput.format(initialPosition.y), zOutput.format(initialPosition.z), - hFormat.format(lengthOffset) - ); - } else { - writeBlock(gAbsIncModal.format(90), gMotionModal.format(0), xOutput.format(initialPosition.x), yOutput.format(initialPosition.y)); - writeBlock( - gMotionModal.format(0), - conditional(!currentSection.isMultiAxis() || (currentSection.getOptimizedTCPMode() == 1), gFormat.format(43)), - conditional(currentSection.isMultiAxis() && (currentSection.getOptimizedTCPMode() == 0), gFormat.format(234)), - zOutput.format(initialPosition.z), - hFormat.format(lengthOffset) - ); - } - } else { - writeBlock( - gAbsIncModal.format(90), - gMotionModal.format(0), - conditional(!currentSection.isMultiAxis() || (currentSection.getOptimizedTCPMode() == 1), gFormat.format(43)), - conditional(currentSection.isMultiAxis() && (currentSection.getOptimizedTCPMode() == 0), gFormat.format(234)), - xOutput.format(initialPosition.x), - yOutput.format(initialPosition.y), - zOutput.format(initialPosition.z), - hFormat.format(lengthOffset) - ); - } - zIsOutput = true; - - gMotionModal.reset(); - } else { - var x = xOutput.format(initialPosition.x); - var y = yOutput.format(initialPosition.y); - if (!properties.useG0 && x && y) { - // axes are not synchronized - writeBlock(gAbsIncModal.format(90), gMotionModal.format(1), x, y, getFeed(highFeedrate)); - } else { - writeBlock(gAbsIncModal.format(90), gMotionModal.format(0), x, y); - } - } - - if (insertToolCall) { - if (properties.preloadTool) { - var nextTool = getNextTool(tool.number); - if (nextTool) { - writeBlock("T" + toolFormat.format(nextTool.number)); - } else { - // preload first tool - var section = getSection(0); - var firstToolNumber = section.getTool().number; - if (tool.number != firstToolNumber) { - writeBlock("T" + toolFormat.format(firstToolNumber)); - } - } - } - } - - if (isProbeOperation()) { - if (g68RotationMode != 0) { - error(localize("You cannot probe while G68 Rotation is in effect.")); - return; - } - angularProbingMode = getAngularProbingMode(); - writeBlock(gFormat.format(65), "P" + 9832); // spin the probe on - } - if (isInspectionOperation(currentSection) && (typeof inspectionProcessSectionStart == "function")) { - inspectionProcessSectionStart(); - } - // define subprogram - subprogramDefine(initialPosition, abc, retracted, zIsOutput); -} - -function onDwell(seconds) { - if (seconds > 99999.999) { - warning(localize("Dwelling time is out of range.")); - } - seconds = clamp(0.001, seconds, 99999.999); - writeBlock(gFeedModeModal.format(94), gFormat.format(4), "P" + milliFormat.format(seconds * 1000)); -} - -function onSpindleSpeed(spindleSpeed) { - writeBlock(sOutput.format(spindleSpeed)); -} - -function onCycle() { - writeBlock(gPlaneModal.format(17)); -} - -function getCommonCycle(x, y, z, r, c) { - forceXYZ(); // force xyz on first drill hole of any cycle - if (incrementalMode) { - zOutput.format(c); - return [xOutput.format(x), yOutput.format(y), - "Z" + xyzFormat.format(z - r), - "R" + xyzFormat.format(r - c)]; - } else { - return [xOutput.format(x), yOutput.format(y), - zOutput.format(z), - "R" + xyzFormat.format(r)]; - } -} - -function setCyclePosition(_position) { - switch (gPlaneModal.getCurrent()) { - case 17: // XY - zOutput.format(_position); - break; - case 18: // ZX - yOutput.format(_position); - break; - case 19: // YZ - xOutput.format(_position); - break; - } -} - -/** Convert approach to sign. */ -function approach(value) { - validate((value == "positive") || (value == "negative"), "Invalid approach."); - return (value == "positive") ? 1 : -1; -} - -/** - Determine if angular probing is supported. -*/ -function getAngularProbingMode() { - if (machineConfiguration.isMultiAxisConfiguration()) { - if (machineConfiguration.isMachineCoordinate(2)) { - return (ANGLE_PROBE_USE_CAXIS); - } else { - return (ANGLE_PROBE_NOT_SUPPORTED); - } - } else { - return (ANGLE_PROBE_USE_ROTATION); - } -} - -/** - Output rotation offset based on angular probing cycle. -*/ -function setProbingAngle() { - if ((g68RotationMode == 1) || (g68RotationMode == 2)) { // Rotate coordinate system for Angle Probing - if (angularProbingMode == ANGLE_PROBE_USE_ROTATION) { - gRotationModal.reset(); - gAbsIncModal.reset(); - var xCode = (g68RotationMode == 1) ? "X0" : "X[#185]"; - var yCode = (g68RotationMode == 1) ? "Y0" : "Y[#186]"; - writeBlock(gRotationModal.format(68), gAbsIncModal.format(90), xCode, yCode, "R[#189]"); - g68RotationMode = 3; - } else if (angularProbingMode == ANGLE_PROBE_USE_CAXIS) { - var workOffset = probeOutputWorkOffset ? probeOutputWorkOffset : currentWorkOffset; - if (workOffset > 6) { - error(localize("Angle Probing only supports work offsets 1-6.")); - return; - } - var param = 5200 + workOffset * 20 + 5; - writeBlock("#" + param + "=" + "#189"); - g68RotationMode = 0; - } else { - error(localize("Angular Probing is not supported for this machine configuration.")); - return; - } - } -} - -function protectedProbeMove(_cycle, x, y, z) { - var _x = xOutput.format(x); - var _y = yOutput.format(y); - var _z = zOutput.format(z); - if (_z && z >= getCurrentPosition().z) { - writeBlock(gFormat.format(65), "P" + 9810, _z, getFeed(cycle.feedrate)); // protected positioning move - } - if (_x || _y) { - writeBlock(gFormat.format(65), "P" + 9810, _x, _y, getFeed(highFeedrate)); // protected positioning move - } - if (_z && z < getCurrentPosition().z) { - writeBlock(gFormat.format(65), "P" + 9810, _z, getFeed(cycle.feedrate)); // protected positioning move - } -} - -function onCyclePoint(x, y, z) { - if (isInspectionOperation(currentSection) && (typeof inspectionCycleInspect == "function")) { - inspectionCycleInspect(cycle, x, y, z); - return; - } - if (!isSameDirection(getRotation().forward, new Vector(0, 0, 1))) { - expandCyclePoint(x, y, z); - return; - } - var probeWorkOffsetCode; - if (isProbeOperation()) { - if (!isSameDirection(currentSection.workPlane.forward, new Vector(0, 0, 1)) && (!cycle.probeMode || (cycle.probeMode == 0)) && properties.useDWO) { - error(localize("Your machine does not support the selected probing operation with DWO enabled.")); - return; - } - protectedProbeMove(cycle, x, y, z); - - var workOffset = probeOutputWorkOffset ? probeOutputWorkOffset : currentWorkOffset; - if (workOffset > 99) { - error(localize("Work offset is out of range.")); - return; - } else if (workOffset > 6) { - probeWorkOffsetCode = "154." + probe154Format.format(workOffset - 6); - } else { - probeWorkOffsetCode = workOffset + "."; // G54->G59 - } - } - - var forceCycle = false; - switch (cycleType) { - case "tapping-with-chip-breaking": - case "left-tapping-with-chip-breaking": - case "right-tapping-with-chip-breaking": - forceCycle = true; - if (!isFirstCyclePoint()) { - writeBlock(gCycleModal.format(80)); - gMotionModal.reset(); - } - } - if (forceCycle || isFirstCyclePoint() || isProbeOperation()) { - if (!isProbeOperation()) { - // return to initial Z which is clearance plane and set absolute mode - repositionToCycleClearance(cycle, x, y, z); - } - - var F = cycle.feedrate; - var P = !cycle.dwell ? 0 : clamp(1, cycle.dwell * 1000, 99999999); // in milliseconds - - switch (cycleType) { - case "drilling": - writeBlock( - gRetractModal.format(98), gCycleModal.format(81), - getCommonCycle(x, y, z, cycle.retract, cycle.clearance), - feedOutput.format(F) - ); - break; - case "counter-boring": - if (P > 0) { - writeBlock( - gRetractModal.format(98), gCycleModal.format(82), - getCommonCycle(x, y, z, cycle.retract, cycle.clearance), - "P" + milliFormat.format(P), // not optional - feedOutput.format(F) - ); - } else { - writeBlock( - gRetractModal.format(98), gCycleModal.format(81), - getCommonCycle(x, y, z, cycle.retract, cycle.clearance), - feedOutput.format(F) - ); - } - break; - case "chip-breaking": - if ((cycle.accumulatedDepth < cycle.depth) && (cycle.incrementalDepthReduction > 0)) { - expandCyclePoint(x, y, z); - } else if (cycle.accumulatedDepth < cycle.depth) { - writeBlock( - gRetractModal.format(98), gCycleModal.format(73), - getCommonCycle(x, y, z, cycle.retract, cycle.clearance), - ("Q" + xyzFormat.format(cycle.incrementalDepth)), - ("K" + xyzFormat.format(cycle.accumulatedDepth)), - conditional(P > 0, "P" + milliFormat.format(P)), // optional - feedOutput.format(F) - ); - } else { - writeBlock( - gRetractModal.format(98), gCycleModal.format(73), - getCommonCycle(x, y, z, cycle.retract, cycle.clearance), - (((cycle.incrementalDepthReduction > 0) ? "I" : "Q") + xyzFormat.format(cycle.incrementalDepth)), - conditional(cycle.incrementalDepthReduction > 0, "J" + xyzFormat.format(cycle.incrementalDepthReduction)), - conditional(cycle.incrementalDepthReduction > 0, "K" + xyzFormat.format(cycle.minimumIncrementalDepth)), - conditional(P > 0, "P" + milliFormat.format(P)), // optional - feedOutput.format(F) - ); - } - break; - case "deep-drilling": - writeBlock( - gRetractModal.format(98), gCycleModal.format(83), - getCommonCycle(x, y, z, cycle.retract, cycle.clearance), - (((cycle.incrementalDepthReduction > 0) ? "I" : "Q") + xyzFormat.format(cycle.incrementalDepth)), - conditional(cycle.incrementalDepthReduction > 0, "J" + xyzFormat.format(cycle.incrementalDepthReduction)), - conditional(cycle.incrementalDepthReduction > 0, "K" + xyzFormat.format(cycle.minimumIncrementalDepth)), - conditional(P > 0, "P" + milliFormat.format(P)), // optional - feedOutput.format(F) - ); - break; - case "tapping": - var tappingFPM = tool.getThreadPitch() * rpmFormat.getResultingValue(spindleSpeed); - F = (properties.useG95forTapping ? tool.getThreadPitch() : tappingFPM); - if (properties.useG95forTapping) { - writeBlock(gFeedModeModal.format(95)); - } - writeBlock( - gRetractModal.format(98), gCycleModal.format((tool.type == TOOL_TAP_LEFT_HAND) ? 74 : 84), - getCommonCycle(x, y, z, cycle.retract, cycle.clearance), - pitchOutput.format(F) - ); - forceFeed(); - break; - case "left-tapping": - var tappingFPM = tool.getThreadPitch() * rpmFormat.getResultingValue(spindleSpeed); - F = (properties.useG95forTapping ? tool.getThreadPitch() : tappingFPM); - if (properties.useG95forTapping) { - writeBlock(gFeedModeModal.format(95)); - } - writeBlock( - gRetractModal.format(98), gCycleModal.format(74), - getCommonCycle(x, y, z, cycle.retract, cycle.clearance), - pitchOutput.format(F) - ); - forceFeed(); - break; - case "right-tapping": - var tappingFPM = tool.getThreadPitch() * rpmFormat.getResultingValue(spindleSpeed); - F = (properties.useG95forTapping ? tool.getThreadPitch() : tappingFPM); - if (properties.useG95forTapping) { - writeBlock(gFeedModeModal.format(95)); - } - writeBlock( - gRetractModal.format(98), gCycleModal.format(84), - getCommonCycle(x, y, z, cycle.retract, cycle.clearance), - pitchOutput.format(F) - ); - forceFeed(); - 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 tapping cycles with chip breaking.")); - return; - } else { - var tappingFPM = tool.getThreadPitch() * rpmFormat.getResultingValue(spindleSpeed); - F = (properties.useG95forTapping ? tool.getThreadPitch() : tappingFPM); - if (properties.useG95forTapping) { - writeBlock(gFeedModeModal.format(95)); - } - // Parameter 57 bit 6, REPT RIG TAP, is set to 1 (On) - // On Mill software versions12.09 and above, REPT RIG TAP has been moved from the Parameters to Setting 133 - var u = cycle.stock; - var step = cycle.incrementalDepth; - var first = true; - while (u > cycle.bottom) { - if (step < cycle.minimumIncrementalDepth) { - step = cycle.minimumIncrementalDepth; - } - u -= step; - step -= cycle.incrementalDepthReduction; - gCycleModal.reset(); // required - if ((u - 0.001) <= cycle.bottom) { - u = cycle.bottom; - } - if (first) { - first = false; - writeBlock( - gRetractModal.format(99), gCycleModal.format((tool.type == TOOL_TAP_LEFT_HAND ? 74 : 84)), - getCommonCycle((gPlaneModal.getCurrent() == 19) ? u : x, (gPlaneModal.getCurrent() == 18) ? u : y, (gPlaneModal.getCurrent() == 17) ? u : z, cycle.retract, cycle.clearance), - pitchOutput.format(F) - ); - } else { - var position; - var depth; - switch (gPlaneModal.getCurrent()) { - case 17: - xOutput.reset(); - position = xOutput.format(x); - depth = "Z" + xyzFormat.format(u); - break; - case 18: - zOutput.reset(); - position = zOutput.format(z); - depth = "Y" + xyzFormat.format(u); - break; - case 19: - yOutput.reset(); - position = yOutput.format(y); - depth = "X" + xyzFormat.format(u); - break; - } - writeBlock(conditional(u <= cycle.bottom, gRetractModal.format(98)), position, depth); - } - } - } - forceFeed(); - break; - case "fine-boring": - writeBlock( - gRetractModal.format(98), gCycleModal.format(76), - getCommonCycle(x, y, z, cycle.retract, cycle.clearance), - "P" + milliFormat.format(P), // not optional - "Q" + xyzFormat.format(cycle.shift), - feedOutput.format(F) - ); - forceSpindleSpeed = true; - break; - case "back-boring": - if (P > 0) { - expandCyclePoint(x, y, z); - } else { - 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), gCycleModal.format(77), - getCommonCycle(x - dx, y - dy, z - dz, cycle.bottom, cycle.clearance), - "Q" + xyzFormat.format(cycle.shift), - feedOutput.format(F) - ); - forceSpindleSpeed = true; - } - break; - case "reaming": - writeBlock( - gRetractModal.format(98), gCycleModal.format(85), - getCommonCycle(x, y, z, cycle.retract, cycle.clearance), - feedOutput.format(F) - ); - break; - case "stop-boring": - if (P > 0) { - expandCyclePoint(x, y, z); - } else { - writeBlock( - gRetractModal.format(98), gCycleModal.format(86), - getCommonCycle(x, y, z, cycle.retract, cycle.clearance), - feedOutput.format(F) - ); - forceSpindleSpeed = true; - } - break; - case "manual-boring": - writeBlock( - gRetractModal.format(98), gCycleModal.format(88), - getCommonCycle(x, y, z, cycle.retract, cycle.clearance), - "P" + milliFormat.format(P), // not optional - feedOutput.format(F) - ); - break; - case "boring": - writeBlock( - gRetractModal.format(98), gCycleModal.format(89), - getCommonCycle(x, y, z, cycle.retract, cycle.clearance), - "P" + milliFormat.format(P), // not optional - feedOutput.format(F) - ); - break; - - case "probing-x": - protectedProbeMove(cycle, x, y, z - cycle.depth); - writeBlock( - gFormat.format(65), "P" + 9811, - "X" + xyzFormat.format(x + approach(cycle.approach1) * (cycle.probeClearance + tool.diameter / 2)), - "Q" + xyzFormat.format(cycle.probeOvertravel), - getProbingArguments(cycle, probeWorkOffsetCode) - ); - break; - case "probing-y": - protectedProbeMove(cycle, x, y, z - cycle.depth); - writeBlock( - gFormat.format(65), "P" + 9811, - "Y" + xyzFormat.format(y + approach(cycle.approach1) * (cycle.probeClearance + tool.diameter / 2)), - "Q" + xyzFormat.format(cycle.probeOvertravel), - getProbingArguments(cycle, probeWorkOffsetCode) - ); - break; - case "probing-z": - protectedProbeMove(cycle, x, y, Math.min(z - cycle.depth + cycle.probeClearance, cycle.retract)); - writeBlock( - gFormat.format(65), "P" + 9811, - "Z" + xyzFormat.format(z - cycle.depth), - "Q" + xyzFormat.format(cycle.probeOvertravel), - getProbingArguments(cycle, probeWorkOffsetCode) - ); - break; - case "probing-x-wall": - protectedProbeMove(cycle, x, y, z); - writeBlock( - gFormat.format(65), "P" + 9812, - "X" + xyzFormat.format(cycle.width1), - zOutput.format(z - cycle.depth), - "Q" + xyzFormat.format(cycle.probeOvertravel), - "R" + xyzFormat.format(cycle.probeClearance), - getProbingArguments(cycle, probeWorkOffsetCode) - ); - break; - case "probing-y-wall": - protectedProbeMove(cycle, x, y, z); - writeBlock( - gFormat.format(65), "P" + 9812, - "Y" + xyzFormat.format(cycle.width1), - zOutput.format(z - cycle.depth), - "Q" + xyzFormat.format(cycle.probeOvertravel), - "R" + xyzFormat.format(cycle.probeClearance), - getProbingArguments(cycle, probeWorkOffsetCode) - ); - break; - case "probing-x-channel": - protectedProbeMove(cycle, x, y, z - cycle.depth); - writeBlock( - gFormat.format(65), "P" + 9812, - "X" + xyzFormat.format(cycle.width1), - "Q" + xyzFormat.format(cycle.probeOvertravel), - // not required "R" + xyzFormat.format(cycle.probeClearance), - getProbingArguments(cycle, probeWorkOffsetCode) - ); - break; - case "probing-x-channel-with-island": - protectedProbeMove(cycle, x, y, z); - writeBlock( - gFormat.format(65), "P" + 9812, - "X" + xyzFormat.format(cycle.width1), - zOutput.format(z - cycle.depth), - "Q" + xyzFormat.format(cycle.probeOvertravel), - "R" + xyzFormat.format(-cycle.probeClearance), - getProbingArguments(cycle, probeWorkOffsetCode) - ); - break; - case "probing-y-channel": - protectedProbeMove(cycle, x, y, z - cycle.depth); - writeBlock( - gFormat.format(65), "P" + 9812, - "Y" + xyzFormat.format(cycle.width1), - "Q" + xyzFormat.format(cycle.probeOvertravel), - // not required "R" + xyzFormat.format(cycle.probeClearance), - getProbingArguments(cycle, probeWorkOffsetCode) - ); - break; - case "probing-y-channel-with-island": - protectedProbeMove(cycle, x, y, z); - writeBlock( - gFormat.format(65), "P" + 9812, - "Y" + xyzFormat.format(cycle.width1), - zOutput.format(z - cycle.depth), - "Q" + xyzFormat.format(cycle.probeOvertravel), - "R" + xyzFormat.format(-cycle.probeClearance), - getProbingArguments(cycle, probeWorkOffsetCode) - ); - break; - case "probing-xy-circular-boss": - protectedProbeMove(cycle, x, y, z); - writeBlock( - gFormat.format(65), "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, probeWorkOffsetCode) - ); - break; - case "probing-xy-circular-hole": - protectedProbeMove(cycle, x, y, z - cycle.depth); - writeBlock( - gFormat.format(65), "P" + 9814, - "D" + xyzFormat.format(cycle.width1), - "Q" + xyzFormat.format(cycle.probeOvertravel), - // not required "R" + xyzFormat.format(cycle.probeClearance), - getProbingArguments(cycle, probeWorkOffsetCode) - ); - break; - case "probing-xy-circular-hole-with-island": - protectedProbeMove(cycle, x, y, z); - writeBlock( - gFormat.format(65), "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, probeWorkOffsetCode) - ); - break; - case "probing-xy-rectangular-hole": - protectedProbeMove(cycle, x, y, z - cycle.depth); - writeBlock( - gFormat.format(65), "P" + 9812, - "X" + xyzFormat.format(cycle.width1), - "Q" + xyzFormat.format(cycle.probeOvertravel), - // not required "R" + xyzFormat.format(-cycle.probeClearance), - getProbingArguments(cycle, probeWorkOffsetCode) - ); - writeBlock( - gFormat.format(65), "P" + 9812, - "Y" + xyzFormat.format(cycle.width2), - "Q" + xyzFormat.format(cycle.probeOvertravel), - // not required "R" + xyzFormat.format(-cycle.probeClearance), - getProbingArguments(cycle, probeWorkOffsetCode) - ); - break; - case "probing-xy-rectangular-boss": - protectedProbeMove(cycle, x, y, z); - writeBlock( - gFormat.format(65), "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, probeWorkOffsetCode) - ); - writeBlock( - gFormat.format(65), "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, probeWorkOffsetCode) - ); - break; - case "probing-xy-rectangular-hole-with-island": - protectedProbeMove(cycle, x, y, z); - writeBlock( - gFormat.format(65), "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, probeWorkOffsetCode) - ); - writeBlock( - gFormat.format(65), "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, probeWorkOffsetCode) - ); - 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 && (cycle.probeSpacing != 0)) { - cornerI = cycle.probeSpacing; - cornerJ = cycle.probeSpacing; - } - if ((cornerI != 0) && (cornerJ != 0)) { - g68RotationMode = 2; - } - protectedProbeMove(cycle, x, y, z - cycle.depth); - writeBlock( - gFormat.format(65), "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), - conditional((g68RotationMode == 0) || (angularProbingMode == ANGLE_PROBE_USE_CAXIS), getProbingArguments(cycle, probeWorkOffsetCode)) - ); - 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 && (cycle.probeSpacing != 0)) { - cornerI = cycle.probeSpacing; - cornerJ = cycle.probeSpacing; - } - if ((cornerI != 0) && (cornerJ != 0)) { - g68RotationMode = 2; - } - protectedProbeMove(cycle, x, y, z - cycle.depth); - writeBlock( - gFormat.format(65), "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), - conditional((g68RotationMode == 0) || (angularProbingMode == ANGLE_PROBE_USE_CAXIS), getProbingArguments(cycle, probeWorkOffsetCode)) - ); - break; - case "probing-x-plane-angle": - protectedProbeMove(cycle, x, y, z - cycle.depth); - writeBlock( - gFormat.format(65), "P" + 9843, - "X" + xyzFormat.format(x + approach(cycle.approach1) * (cycle.probeClearance + tool.diameter / 2)), - "D" + xyzFormat.format(cycle.probeSpacing), - "Q" + xyzFormat.format(cycle.probeOvertravel), - getProbingArguments(cycle, false) - ); - g68RotationMode = 1; - break; - case "probing-y-plane-angle": - protectedProbeMove(cycle, x, y, z - cycle.depth); - writeBlock( - gFormat.format(65), "P" + 9843, - "Y" + xyzFormat.format(y + approach(cycle.approach1) * (cycle.probeClearance + tool.diameter / 2)), - "D" + xyzFormat.format(cycle.probeSpacing), - "Q" + xyzFormat.format(cycle.probeOvertravel), - getProbingArguments(cycle, false) - ); - g68RotationMode = 1; - break; - - default: - expandCyclePoint(x, y, z); - } - - // place cycle operation in subprogram - if (cycleSubprogramIsActive) { - if (forceCycle || cycleExpanded || isProbeOperation()) { - cycleSubprogramIsActive = false; - } else { - // call subprogram - writeBlock(mFormat.format(97), "P" + nFormat.format(currentSubprogram)); - subprogramStart(new Vector(x, y, z), new Vector(0, 0, 0), false); - } - } - if (incrementalMode) { // set current position to clearance height - setCyclePosition(cycle.clearance); - } - - // 2nd through nth cycle point - } else { - if (cycleExpanded) { - expandCyclePoint(x, y, z); - } else { - var _x; - var _y; - var _z; - if (!xyzFormat.areDifferent(x, xOutput.getCurrent()) && - !xyzFormat.areDifferent(y, yOutput.getCurrent()) && - !xyzFormat.areDifferent(z, zOutput.getCurrent())) { - switch (gPlaneModal.getCurrent()) { - case 17: // XY - xOutput.reset(); // at least one axis is required - break; - case 18: // ZX - zOutput.reset(); // at least one axis is required - break; - case 19: // YZ - yOutput.reset(); // at least one axis is required - break; - } - } - if (incrementalMode) { // set current position to retract height - setCyclePosition(cycle.retract); - } - writeBlock(xOutput.format(x), yOutput.format(y), zOutput.format(z)); - if (incrementalMode) { // set current position to clearance height - setCyclePosition(cycle.clearance); - } - } - } -} - -function getProbingArguments(cycle, probeWorkOffsetCode) { - var probeWCS = hasParameter("operation-strategy") && (getParameter("operation-strategy") == "probe"); - 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(probeWorkOffsetCode && probeWCS, "S" + probeWorkOffsetCode) - ]; -} - -function onCycleEnd() { - if (isProbeOperation()) { - zOutput.reset(); - gMotionModal.reset(); - writeBlock(gFormat.format(65), "P" + 9810, zOutput.format(cycle.retract)); // protected retract move - } else { - if (cycleSubprogramIsActive) { - subprogramEnd(); - cycleSubprogramIsActive = false; - } - if (!cycleExpanded) { - writeBlock(gCycleModal.format(80), conditional(properties.useG95forTapping, gFeedModeModal.format(94))); - gMotionModal.reset(); - } - } -} - -var pendingRadiusCompensation = -1; - -function onRadiusCompensation() { - pendingRadiusCompensation = radiusCompensation; -} - -function onRapid(_x, _y, _z) { - var x = xOutput.format(_x); - var y = yOutput.format(_y); - var z = zOutput.format(_z); - if (x || y || z) { - if (pendingRadiusCompensation >= 0) { - error(localize("Radius compensation mode cannot be changed at rapid traversal.")); - return; - } - if (!properties.useG0 && (((x ? 1 : 0) + (y ? 1 : 0) + (z ? 1 : 0)) > 1)) { - // axes are not synchronized - writeBlock(gMotionModal.format(1), x, y, z, getFeed(highFeedrate)); - } else { - writeBlock(gMotionModal.format(0), x, y, z); - forceFeed(); - } - } -} - -function onLinear(_x, _y, _z, feed) { - if (pendingRadiusCompensation >= 0) { - // ensure that we end at desired position when compensation is turned off - xOutput.reset(); - yOutput.reset(); - } - var x = xOutput.format(_x); - var y = yOutput.format(_y); - var z = zOutput.format(_z); - var f = getFeed(feed); - if (x || y || z) { - if (pendingRadiusCompensation >= 0) { - pendingRadiusCompensation = -1; - var d = tool.diameterOffset; - if ((d > 200 && d < 1000) || d > 9999) { - warning(localize("Diameter offset out of range.")); - } - writeBlock(gPlaneModal.format(17)); - switch (radiusCompensation) { - case RADIUS_COMPENSATION_LEFT: - dOutput.reset(); - writeBlock(gMotionModal.format(1), gFormat.format(41), x, y, z, dOutput.format(d), f); - break; - case RADIUS_COMPENSATION_RIGHT: - dOutput.reset(); - writeBlock(gMotionModal.format(1), gFormat.format(42), x, y, z, dOutput.format(d), f); - break; - default: - writeBlock(gMotionModal.format(1), gFormat.format(40), x, y, z, f); - } - } else { - writeBlock(gMotionModal.format(1), x, y, z, f); - } - } else if (f) { - if (getNextRecord().isMotion()) { // try not to output feed without motion - forceFeed(); // force feed on next line - } else { - writeBlock(gMotionModal.format(1), f); - } - } -} - -function onRapid5D(_x, _y, _z, _a, _b, _c) { - if (!currentSection.isOptimizedForMachine()) { - error(localize("This post configuration has not been customized for 5-axis simultaneous toolpath.")); - return; - } - if (pendingRadiusCompensation >= 0) { - error(localize("Radius compensation mode cannot be changed at rapid traversal.")); - return; - } - var x = xOutput.format(_x); - var y = yOutput.format(_y); - var z = zOutput.format(_z); - var a = aOutput.format(_a); - var b = bOutput.format(_b); - var c = cOutput.format(_c); - if (true) { // required for multi-axis - // axes are not synchronized - writeBlock(gMotionModal.format(1), x, y, z, a, b, c, getFeed(highFeedrate)); - } else { - writeBlock(gMotionModal.format(0), x, y, z, a, b, c); - forceFeed(); - } -} - -function onLinear5D(_x, _y, _z, _a, _b, _c, feed) { - if (!currentSection.isOptimizedForMachine()) { - error(localize("This post configuration has not been customized for 5-axis simultaneous toolpath.")); - return; - } - if (pendingRadiusCompensation >= 0) { - error(localize("Radius compensation cannot be activated/deactivated for 5-axis move.")); - return; - } - - var x = xOutput.format(_x); - var y = yOutput.format(_y); - var z = zOutput.format(_z); - var a = aOutput.format(_a); - var b = bOutput.format(_b); - var c = cOutput.format(_c); - - // get feedrate number - var f = {frn:0, fmode:0}; - if ((a || b || c) && !properties.useTCPC) { - f = getMultiaxisFeed(_x, _y, _z, _a, _b, _c, feed); - if (properties.useDPMFeeds) { - f.frn = feedOutput.format(f.frn); - } else { - f.frn = inverseTimeOutput.format(f.frn); - } - } else { - f.frn = feedOutput.format(feed); - f.fmode = 94; - } - - if (x || y || z || a || b || c) { - writeBlock(gFeedModeModal.format(f.fmode), gMotionModal.format(1), x, y, z, a, b, c, f.frn); - } else if (f.frn) { - if (getNextRecord().isMotion()) { // try not to output feed without motion - feedOutput.reset(); // force feed on next line - } else { - writeBlock(gFeedModeModal.format(f.fmode), gMotionModal.format(1), f.frn); - } - } -} - -// Start of multi-axis feedrate logic -/***** Be sure to add 'useInverseTime' to post properties if necessary. *****/ -/***** 'inverseTimeOutput' should be defined if Inverse Time feedrates are supported. *****/ -/***** 'previousABC' can be added throughout to maintain previous rotary positions. Required for Mill/Turn machines. *****/ -/***** 'headOffset' should be defined when a head rotary axis is defined. *****/ -/***** The feedrate mode must be included in motion block output (linear, circular, etc.) for Inverse Time feedrate support. *****/ -var dpmBPW = 0.1; // ratio of rotary accuracy to linear accuracy for DPM calculations -var inverseTimeUnits = 1.0; // 1.0 = minutes, 60.0 = seconds -var maxInverseTime = 9999; // maximum value to output for Inverse Time feeds -var maxDPM = 9999.99; // maximum value to output for DPM feeds -var previousDPMFeed = 0; // previously output DPM feed -var dpmFeedToler = 0.5; // tolerance to determine when the DPM feed has changed -// var previousABC = new Vector(0, 0, 0); // previous ABC position if maintained in post, don't define if not used -var forceOptimized = undefined; // used to override optimized-for-angles points (XZC-mode) - -/** Calculate the multi-axis feedrate number. */ -function getMultiaxisFeed(_x, _y, _z, _a, _b, _c, feed) { - var f = {frn:0, fmode:0}; - if (feed <= 0) { - error(localize("Feedrate is less than or equal to 0.")); - return f; - } - - var length = getMoveLength(_x, _y, _z, _a, _b, _c); - - if (!properties.useDPMFeeds) { // inverse time - f.frn = getInverseTime(length.tool, feed); - f.fmode = 93; - feedOutput.reset(); - } else { // degrees per minute - f.frn = getFeedDPM(length, feed); - f.fmode = 94; - } - return f; -} - -/** Returns point optimization mode. */ -function getOptimizedMode() { - if (forceOptimized != undefined) { - return forceOptimized; - } - // return (currentSection.getOptimizedTCPMode() != 0); // TAG:doesn't return correct value - return true; // always return false for non-TCP based heads -} - -/** Calculate the DPM feedrate number. */ -function getFeedDPM(_moveLength, _feed) { - if ((_feed == 0) || (_moveLength.tool < 0.0001) || (toDeg(_moveLength.abcLength) < 0.0005)) { - previousDPMFeed = 0; - return _feed; - } - var moveTime = _moveLength.tool / _feed; - if (moveTime == 0) { - previousDPMFeed = 0; - return _feed; - } - - var dpmFeed; - var tcp = false; // !getOptimizedMode() && (forceOptimized == undefined); // set to false for rotary heads - if (tcp) { // TCP mode is supported, output feed as FPM - dpmFeed = _feed; - } else if (false) { // standard DPM - dpmFeed = Math.min(toDeg(_moveLength.abcLength) / moveTime, maxDPM); - if (Math.abs(dpmFeed - previousDPMFeed) < dpmFeedToler) { - dpmFeed = previousDPMFeed; - } - } else if (true) { // combination FPM/DPM - var length = Math.sqrt(Math.pow(_moveLength.xyzLength, 2.0) + Math.pow((toDeg(_moveLength.abcLength) * dpmBPW), 2.0)); - dpmFeed = Math.min((length / moveTime), maxDPM); - if (Math.abs(dpmFeed - previousDPMFeed) < dpmFeedToler) { - dpmFeed = previousDPMFeed; - } - } else { // machine specific calculation - dpmFeed = _feed; - } - previousDPMFeed = dpmFeed; - return dpmFeed; -} - -/** Calculate the Inverse time feedrate number. */ -function getInverseTime(_length, _feed) { - var inverseTime; - if (_length < 1.e-6) { // tool doesn't move - if (typeof maxInverseTime === "number") { - inverseTime = maxInverseTime; - } else { - inverseTime = 999999; - } - } else { - inverseTime = _feed / _length / inverseTimeUnits; - if (typeof maxInverseTime === "number") { - if (inverseTime > maxInverseTime) { - inverseTime = maxInverseTime; - } - } - } - return inverseTime; -} - -/** Calculate radius for each rotary axis. */ -function getRotaryRadii(startTool, endTool, startABC, endABC) { - var radii = new Vector(0, 0, 0); - var startRadius; - var endRadius; - var axis = new Array(machineConfiguration.getAxisU(), machineConfiguration.getAxisV(), machineConfiguration.getAxisW()); - for (var i = 0; i < 3; ++i) { - if (axis[i].isEnabled()) { - var startRadius = getRotaryRadius(axis[i], startTool, startABC); - var endRadius = getRotaryRadius(axis[i], endTool, endABC); - radii.setCoordinate(axis[i].getCoordinate(), Math.max(startRadius, endRadius)); - } - } - return radii; -} - -/** Calculate the distance of the tool position to the center of a rotary axis. */ -function getRotaryRadius(axis, toolPosition, abc) { - if (!axis.isEnabled()) { - return 0; - } - - var direction = axis.getEffectiveAxis(); - var normal = direction.getNormalized(); - // calculate the rotary center based on head/table - var center; - var radius; - if (axis.isHead()) { - var pivot; - if (typeof headOffset === "number") { - pivot = headOffset; - } else { - pivot = tool.getBodyLength(); - } - if (axis.getCoordinate() == machineConfiguration.getAxisU().getCoordinate()) { // rider - center = Vector.sum(toolPosition, Vector.product(machineConfiguration.getDirection(abc), pivot)); - center = Vector.sum(center, axis.getOffset()); - radius = Vector.diff(toolPosition, center).length; - } else { // carrier - var angle = abc.getCoordinate(machineConfiguration.getAxisU().getCoordinate()); - radius = Math.abs(pivot * Math.sin(angle)); - radius += axis.getOffset().length; - } - } else { - center = axis.getOffset(); - var d1 = toolPosition.x - center.x; - var d2 = toolPosition.y - center.y; - var d3 = toolPosition.z - center.z; - var radius = Math.sqrt( - Math.pow((d1 * normal.y) - (d2 * normal.x), 2.0) + - Math.pow((d2 * normal.z) - (d3 * normal.y), 2.0) + - Math.pow((d3 * normal.x) - (d1 * normal.z), 2.0) - ); - } - return radius; -} - -/** Calculate the linear distance based on the rotation of a rotary axis. */ -function getRadialDistance(radius, startABC, endABC) { - // calculate length of radial move - var delta = Math.abs(endABC - startABC); - if (delta > Math.PI) { - delta = 2 * Math.PI - delta; - } - var radialLength = (2 * Math.PI * radius) * (delta / (2 * Math.PI)); - return radialLength; -} - -/** Calculate tooltip, XYZ, and rotary move lengths. */ -function getMoveLength(_x, _y, _z, _a, _b, _c) { - // get starting and ending positions - var moveLength = {}; - var startTool; - var endTool; - var startXYZ; - var endXYZ; - var startABC; - if (typeof previousABC !== "undefined") { - startABC = new Vector(previousABC.x, previousABC.y, previousABC.z); - } else { - startABC = getCurrentDirection(); - } - var endABC = new Vector(_a, _b, _c); - - if (!getOptimizedMode()) { // calculate XYZ from tool tip - startTool = getCurrentPosition(); - endTool = new Vector(_x, _y, _z); - startXYZ = startTool; - endXYZ = endTool; - - // adjust points for tables - if (!machineConfiguration.getTableABC(startABC).isZero() || !machineConfiguration.getTableABC(endABC).isZero()) { - startXYZ = machineConfiguration.getOrientation(machineConfiguration.getTableABC(startABC)).getTransposed().multiply(startXYZ); - endXYZ = machineConfiguration.getOrientation(machineConfiguration.getTableABC(endABC)).getTransposed().multiply(endXYZ); - } - - // adjust points for heads - if (machineConfiguration.getAxisU().isEnabled() && machineConfiguration.getAxisU().isHead()) { - if (typeof getOptimizedHeads === "function") { // use post processor function to adjust heads - startXYZ = getOptimizedHeads(startXYZ.x, startXYZ.y, startXYZ.z, startABC.x, startABC.y, startABC.z); - endXYZ = getOptimizedHeads(endXYZ.x, endXYZ.y, endXYZ.z, endABC.x, endABC.y, endABC.z); - } else { // guess at head adjustments - var startDisplacement = machineConfiguration.getDirection(startABC); - startDisplacement.multiply(headOffset); - var endDisplacement = machineConfiguration.getDirection(endABC); - endDisplacement.multiply(headOffset); - startXYZ = Vector.sum(startTool, startDisplacement); - endXYZ = Vector.sum(endTool, endDisplacement); - } - } - } else { // calculate tool tip from XYZ, heads are always programmed in TCP mode, so not handled here - startXYZ = getCurrentPosition(); - endXYZ = new Vector(_x, _y, _z); - startTool = machineConfiguration.getOrientation(machineConfiguration.getTableABC(startABC)).multiply(startXYZ); - endTool = machineConfiguration.getOrientation(machineConfiguration.getTableABC(endABC)).multiply(endXYZ); - } - - // calculate axes movements - moveLength.xyz = Vector.diff(endXYZ, startXYZ).abs; - moveLength.xyzLength = moveLength.xyz.length; - moveLength.abc = Vector.diff(endABC, startABC).abs; - for (var i = 0; i < 3; ++i) { - if (moveLength.abc.getCoordinate(i) > Math.PI) { - moveLength.abc.setCoordinate(i, 2 * Math.PI - moveLength.abc.getCoordinate(i)); - } - } - moveLength.abcLength = moveLength.abc.length; - - // calculate radii - moveLength.radius = getRotaryRadii(startTool, endTool, startABC, endABC); - - // calculate the radial portion of the tool tip movement - var radialLength = Math.sqrt( - Math.pow(getRadialDistance(moveLength.radius.x, startABC.x, endABC.x), 2.0) + - Math.pow(getRadialDistance(moveLength.radius.y, startABC.y, endABC.y), 2.0) + - Math.pow(getRadialDistance(moveLength.radius.z, startABC.z, endABC.z), 2.0) - ); - - // calculate the tool tip move length - // tool tip distance is the move distance based on a combination of linear and rotary axes movement - moveLength.tool = moveLength.xyzLength + radialLength; - - // debug - if (false) { - writeComment("DEBUG - tool = " + moveLength.tool); - writeComment("DEBUG - xyz = " + moveLength.xyz); - var temp = Vector.product(moveLength.abc, 180 / Math.PI); - writeComment("DEBUG - abc = " + temp); - writeComment("DEBUG - radius = " + moveLength.radius); - } - return moveLength; -} -// End of multi-axis feedrate logic - -// Start of onRewindMachine logic -/***** Be sure to add 'safeRetractDistance' to post properties. *****/ -var performRewinds = false; // enables the onRewindMachine logic -var safeRetractFeed = (unit == IN) ? 20 : 500; -var safePlungeFeed = (unit == IN) ? 10 : 250; -var stockAllowance = (unit == IN) ? 0.1 : 2.5; - -/** Allow user to override the onRewind logic. */ -function onRewindMachineEntry(_a, _b, _c) { - return false; -} - -/** Retract to safe position before indexing rotaries. */ -function moveToSafeRetractPosition(isRetracted) { - if (properties.useG28) { - if (!isRetracted) { - writeRetract(Z); - } - if (false) { - writeRetract(X, Y); - } - } else { - if (!isRetracted) { - writeRetract(Z); - } - if (false) { // e.g. when machining very big parts - writeRetract(X, Y); - } - } -} - -/** Return from safe position after indexing rotaries. */ -function returnFromSafeRetractPosition(position) { - forceXYZ(); - xOutput.reset(); - yOutput.reset(); - zOutput.disable(); - onExpandedRapid(position.x, position.y, position.z); - zOutput.enable(); - onExpandedRapid(position.x, position.y, position.z); -} - -/** Determine if a point is on the correct side of a box side. */ -function isPointInBoxSide(point, side) { - var inBox = false; - switch (side.side) { - case "-X": - if (point.x >= side.distance) { - inBox = true; - } - break; - case "-Y": - if (point.y >= side.distance) { - inBox = true; - } - break; - case "-Z": - if (point.z >= side.distance) { - inBox = true; - } - break; - case "X": - if (point.x <= side.distance) { - inBox = true; - } - break; - case "Y": - if (point.y <= side.distance) { - inBox = true; - } - break; - case "Z": - if (point.z <= side.distance) { - inBox = true; - } - break; - } - return inBox; -} - -/** Intersect a point-vector with a plane. */ -function intersectPlane(point, direction, plane) { - var normal = new Vector(plane.x, plane.y, plane.z); - var cosa = Vector.dot(normal, direction); - if (Math.abs(cosa) <= 1.0e-6) { - return undefined; - } - var distance = (Vector.dot(normal, point) - plane.distance) / cosa; - var intersection = Vector.diff(point, Vector.product(direction, distance)); - - if (!isSameDirection(Vector.diff(intersection, point).getNormalized(), direction)) { - return undefined; - } - return intersection; -} - -/** Intersect the point-vector with the stock box. */ -function intersectStock(point, direction) { - var stock = getWorkpiece(); - var sides = new Array( - {x:1, y:0, z:0, distance:stock.lower.x, side:"-X"}, - {x:0, y:1, z:0, distance:stock.lower.y, side:"-Y"}, - {x:0, y:0, z:1, distance:stock.lower.z, side:"-Z"}, - {x:1, y:0, z:0, distance:stock.upper.x, side:"X"}, - {x:0, y:1, z:0, distance:stock.upper.y, side:"Y"}, - {x:0, y:0, z:1, distance:stock.upper.z, side:"Z"} - ); - var intersection = undefined; - var currentDistance = 999999.0; - var localExpansion = -stockAllowance; - for (var i = 0; i < sides.length; ++i) { - if (i == 3) { - localExpansion = -localExpansion; - } - if (isPointInBoxSide(point, sides[i])) { // only consider points within stock box - var location = intersectPlane(point, direction, sides[i]); - if (location != undefined) { - if ((Vector.diff(point, location).length < currentDistance) || currentDistance == 0) { - intersection = location; - currentDistance = Vector.diff(point, location).length; - } - } - } - } - return intersection; -} - -/** Calculates the retract point using the stock box and safe retract distance. */ -function getRetractPosition(currentPosition, currentDirection) { - var retractPos = intersectStock(currentPosition, currentDirection); - if (retractPos == undefined) { - if (tool.getFluteLength() != 0) { - retractPos = Vector.sum(currentPosition, Vector.product(currentDirection, tool.getFluteLength())); - } - } - if ((retractPos != undefined) && properties.safeRetractDistance) { - retractPos = Vector.sum(retractPos, Vector.product(currentDirection, properties.safeRetractDistance)); - } - return retractPos; -} - -/** Determines if the angle passed to onRewindMachine is a valid starting position. */ -function isRewindAngleValid(_a, _b, _c) { - // make sure the angles are different from the last output angles - if (!abcFormat.areDifferent(getCurrentDirection().x, _a) && - !abcFormat.areDifferent(getCurrentDirection().y, _b) && - !abcFormat.areDifferent(getCurrentDirection().z, _c)) { - error( - localize("REWIND: Rewind angles are the same as the previous angles: ") + - abcFormat.format(_a) + ", " + abcFormat.format(_b) + ", " + abcFormat.format(_c) - ); - return false; - } - - // make sure angles are within the limits of the machine - var abc = new Array(_a, _b, _c); - var ix = machineConfiguration.getAxisU().getCoordinate(); - var failed = false; - if ((ix != -1) && !machineConfiguration.getAxisU().isSupported(abc[ix])) { - failed = true; - } - ix = machineConfiguration.getAxisV().getCoordinate(); - if ((ix != -1) && !machineConfiguration.getAxisV().isSupported(abc[ix])) { - failed = true; - } - ix = machineConfiguration.getAxisW().getCoordinate(); - if ((ix != -1) && !machineConfiguration.getAxisW().isSupported(abc[ix])) { - failed = true; - } - if (failed) { - error( - localize("REWIND: Rewind angles are outside the limits of the machine: ") + - abcFormat.format(_a) + ", " + abcFormat.format(_b) + ", " + abcFormat.format(_c) - ); - return false; - } - - return true; -} - -function onRewindMachine(_a, _b, _c) { - - if (!performRewinds) { - error(localize("REWIND: Rewind of machine is required for simultaneous multi-axis toolpath and has been disabled.")); - return; - } - - // Allow user to override rewind logic - if (onRewindMachineEntry(_a, _b, _c)) { - return; - } - - // Determine if input angles are valid or will cause a crash - if (!isRewindAngleValid(_a, _b, _c)) { - error( - localize("REWIND: Rewind angles are invalid:") + - abcFormat.format(_a) + ", " + abcFormat.format(_b) + ", " + abcFormat.format(_c) - ); - return; - } - - // Work with the tool end point - if (currentSection.getOptimizedTCPMode() == 0) { - currentTool = getCurrentPosition(); - } else { - currentTool = machineConfiguration.getOrientation(getCurrentDirection()).multiply(getCurrentPosition()); - } - var currentABC = getCurrentDirection(); - var currentDirection = machineConfiguration.getDirection(currentABC); - - // Calculate the retract position - var retractPosition = getRetractPosition(currentTool, currentDirection); - - // Output warning that axes take longest route - if (retractPosition == undefined) { - error(localize("REWIND: Cannot calculate retract position.")); - return; - } else { - var text = localize("REWIND: Tool is retracting due to rotary axes limits."); - warning(text); - writeComment(text); - } - - // Move to retract position - var position; - if (currentSection.getOptimizedTCPMode() == 0) { - position = retractPosition; - } else { - position = machineConfiguration.getOrientation(getCurrentDirection()).getTransposed().multiply(retractPosition); - } - onExpandedLinear(position.x, position.y, position.z, safeRetractFeed); - - // Cancel TCP so that tool doesn't follow tables - writeBlock(gFormat.format(49), formatComment("TCPC OFF")); - - //Position to safe machine position for rewinding axes - moveToSafeRetractPosition(false); - - // Rotate axes to new position above reentry position - xOutput.disable(); - yOutput.disable(); - zOutput.disable(); - onRapid5D(position.x, position.y, position.z, _a, _b, _c); - xOutput.enable(); - yOutput.enable(); - zOutput.enable(); - - // Reinstate TCP - writeBlock(gFormat.format(234), hFormat.format(tool.lengthOffset), formatComment("TCPC ON")); - - // Move back to position above part - if (currentSection.getOptimizedTCPMode() != 0) { - position = machineConfiguration.getOrientation(new Vector(_a, _b, _c)).getTransposed().multiply(retractPosition); - } - returnFromSafeRetractPosition(position); - - // Plunge tool back to original position - if (currentSection.getOptimizedTCPMode() != 0) { - currentTool = machineConfiguration.getOrientation(new Vector(_a, _b, _c)).getTransposed().multiply(currentTool); - } - onExpandedLinear(currentTool.x, currentTool.y, currentTool.z, safePlungeFeed); -} -// End of onRewindMachine logic - -function onCircular(clockwise, cx, cy, cz, x, y, z, feed) { - if (isSpiral()) { - var startRadius = getCircularStartRadius(); - var endRadius = getCircularRadius(); - var dr = Math.abs(endRadius - startRadius); - if (dr > maximumCircularRadiiDifference) { // maximum limit - linearize(tolerance); // or alternatively use other G-codes for spiral motion - return; - } - } - - if (pendingRadiusCompensation >= 0) { - error(localize("Radius compensation cannot be activated/deactivated for a circular move.")); - return; - } - - var start = getCurrentPosition(); - - if (isFullCircle()) { - if (properties.useRadius || isHelical()) { // radius mode does not support full arcs - linearize(tolerance); - return; - } - switch (getCircularPlane()) { - case PLANE_XY: - writeBlock(gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), getFeed(feed)); - break; - case PLANE_ZX: - writeBlock(gPlaneModal.format(18), gMotionModal.format(clockwise ? 2 : 3), iOutput.format(cx - start.x, 0), kOutput.format(cz - start.z, 0), getFeed(feed)); - break; - case PLANE_YZ: - writeBlock(gPlaneModal.format(19), gMotionModal.format(clockwise ? 2 : 3), jOutput.format(cy - start.y, 0), kOutput.format(cz - start.z, 0), getFeed(feed)); - break; - default: - linearize(tolerance); - } - } else if (!properties.useRadius) { - switch (getCircularPlane()) { - case PLANE_XY: - writeBlock(gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), getFeed(feed)); - break; - case PLANE_ZX: - writeBlock(gPlaneModal.format(18), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), iOutput.format(cx - start.x, 0), kOutput.format(cz - start.z, 0), getFeed(feed)); - break; - case PLANE_YZ: - writeBlock(gPlaneModal.format(19), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), jOutput.format(cy - start.y, 0), kOutput.format(cz - start.z, 0), getFeed(feed)); - break; - default: - linearize(tolerance); - } - } else { // use radius mode - var r = getCircularRadius(); - if (toDeg(getCircularSweep()) > (180 + 1e-9)) { - r = -r; // allow up to <360 deg arcs - } - switch (getCircularPlane()) { - case PLANE_XY: - writeBlock(gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), "R" + rFormat.format(r), getFeed(feed)); - break; - case PLANE_ZX: - writeBlock(gPlaneModal.format(18), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), "R" + rFormat.format(r), getFeed(feed)); - break; - case PLANE_YZ: - writeBlock(gPlaneModal.format(19), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), "R" + rFormat.format(r), getFeed(feed)); - break; - default: - linearize(tolerance); - } - } -} - -var currentCoolantMode = COOLANT_OFF; -var coolantOff = undefined; -var isOptionalCoolant = false; - -function setCoolant(coolant) { - var coolantCodes = getCoolantCodes(coolant); - if (Array.isArray(coolantCodes)) { - if (singleLineCoolant) { - writeBlock((isOptionalCoolant ? "/" : ""), coolantCodes.join(getWordSeparator())); - } else { - for (var c in coolantCodes) { - writeBlock((isOptionalCoolant ? "/" : ""), coolantCodes[c]); - } - } - return undefined; - } - return coolantCodes; -} - -function getCoolantCodes(coolant) { - isOptionalCoolant = false; - var multipleCoolantBlocks = new Array(); // create a formatted array to be passed into the outputted line - if (!coolants) { - error(localize("Coolants have not been defined.")); - } - if (isProbeOperation()) { // avoid coolant output for probing - coolant = COOLANT_OFF; - } - if (coolant == currentCoolantMode) { - if (properties.safeStartAllOperations) { - isOptionalCoolant = true; - } else { - return undefined; // coolant is already active - } - } - if ((coolant != COOLANT_OFF) && (currentCoolantMode != COOLANT_OFF) && !isOptionalCoolant) { - if (Array.isArray(coolantOff)) { - for (var i in coolantOff) { - multipleCoolantBlocks.push(mFormat.format(coolantOff[i])); - } - } else { - multipleCoolantBlocks.push(mFormat.format(coolantOff)); - } - } - - 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(mFormat.format(m[i])); - } - } else { - multipleCoolantBlocks.push(mFormat.format(m)); - } - currentCoolantMode = coolant; - return multipleCoolantBlocks; // return the single formatted coolant value - } - return undefined; -} - -var mapCommand = { - COMMAND_STOP:0, - COMMAND_OPTIONAL_STOP:1, - COMMAND_END:2, - COMMAND_SPINDLE_CLOCKWISE:3, - COMMAND_SPINDLE_COUNTERCLOCKWISE:4, - COMMAND_STOP_SPINDLE:5, - COMMAND_ORIENTATE_SPINDLE:19, - COMMAND_LOAD_TOOL:6 -}; - -function onCommand(command) { - switch (command) { - case COMMAND_STOP: - writeBlock(mFormat.format(0)); - forceSpindleSpeed = true; - return; - case COMMAND_OPTIONAL_STOP: - writeBlock(mFormat.format(1)); - forceSpindleSpeed = true; - return; - case COMMAND_COOLANT_ON: - setCoolant(COOLANT_FLOOD); - return; - case COMMAND_COOLANT_OFF: - setCoolant(COOLANT_OFF); - return; - case COMMAND_START_SPINDLE: - onCommand(tool.clockwise ? COMMAND_SPINDLE_CLOCKWISE : COMMAND_SPINDLE_COUNTERCLOCKWISE); - return; - case COMMAND_LOCK_MULTI_AXIS: - if (machineConfiguration.isMultiAxisConfiguration() && (machineConfiguration.getNumberOfAxes() >= 4)) { - writeBlock(operationNeedsSafeWorkPlane ? "/" : "", mFormat.format(10)); // lock 4th-axis motion - if (machineConfiguration.getNumberOfAxes() == 5) { - writeBlock(operationNeedsSafeWorkPlane ? "/" : "", mFormat.format(12)); // lock 5th-axis motion - } - } - return; - case COMMAND_UNLOCK_MULTI_AXIS: - if (machineConfiguration.isMultiAxisConfiguration() && (machineConfiguration.getNumberOfAxes() >= 4)) { - writeBlock(operationNeedsSafeWorkPlane ? "/" : "", mFormat.format(11)); // unlock 4th-axis motion - if (machineConfiguration.getNumberOfAxes() == 5) { - writeBlock(operationNeedsSafeWorkPlane ? "/" : "", mFormat.format(13)); // unlock 5th-axis motion - } - } - return; - case COMMAND_BREAK_CONTROL: - if (!toolChecked) { // avoid duplicate COMMAND_BREAK_CONTROL - onCommand(COMMAND_STOP_SPINDLE); - onCommand(COMMAND_COOLANT_OFF); - - var retract = false; - if (currentSection.isMultiAxis()) { - if (getCurrentDirection().length != 0) { - retract = true; - } - } else if ((currentWorkPlaneABC != undefined) && (currentWorkPlaneABC.length != 0)) { - retract = true; - } - if (retract) { // move to safe position - moveToSafeRetractPosition(false); - } - - if (activeG254) { // cancel DWO - writeBlock(gFormat.format(255)); - activeG254 = false; - } - - if (retract) { // position rotary axes at 0-degrees - writeBlock( - gMotionModal.format(0), - conditional(machineConfiguration.isMachineCoordinate(0), "A" + abcFormat.format(0)), - conditional(machineConfiguration.isMachineCoordinate(1), "B" + abcFormat.format(0)), - conditional(machineConfiguration.isMachineCoordinate(2), "C" + abcFormat.format(0)) - ); - } - - writeBlock( - gFormat.format(65), - "P" + 9853, - "T" + toolFormat.format(tool.number), - "B" + xyzFormat.format(0), - "H" + xyzFormat.format(properties.toolBreakageTolerance) - ); - toolChecked = true; - } - return; - case COMMAND_TOOL_MEASURE: - measureTool = true; - return; - case COMMAND_START_CHIP_TRANSPORT: - writeBlock(mFormat.format(31)); - return; - case COMMAND_STOP_CHIP_TRANSPORT: - writeBlock(mFormat.format(33)); - 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); - } -} - -var toolChecked = false; // specifies that the tool has been checked with the probe - -function onSectionEnd() { - if (typeof inspectionProcessSectionEnd == "function") { - inspectionProcessSectionEnd(); - } - if (!isLastSection() && (getNextSection().getTool().coolant != tool.coolant)) { - setCoolant(COOLANT_OFF); - } - if ((((getCurrentSectionId() + 1) >= getNumberOfSections()) || - (tool.number != getNextSection().getTool().number)) && - tool.breakControl) { - onCommand(COMMAND_BREAK_CONTROL); - } else { - toolChecked = false; - } - - if (true) { - if (isRedirecting()) { - if (firstPattern) { - var finalPosition = getFramePosition(currentSection.getFinalPosition()); - var abc; - if (currentSection.isMultiAxis() && machineConfiguration.isMultiAxisConfiguration()) { - abc = currentSection.getFinalToolAxisABC(); - } else { - abc = currentWorkPlaneABC; - } - if (abc == undefined) { - abc = new Vector(0, 0, 0); - } - setAbsoluteMode(finalPosition, abc); - subprogramEnd(); - } - } - } - forceAny(); - - if (currentSection.isMultiAxis() && (currentSection.getOptimizedTCPMode() == 0)) { - writeBlock(gFormat.format(49), "(TCPC OFF)"); - } - if (isProbeOperation()) { - writeBlock(gFormat.format(65), "P" + 9833); // spin the probe off - setProbingAngle(); // define rotation of part - } - - operationNeedsSafeStart = false; // reset for next section - operationNeedsSafeToolCall = false; - operationNeedsSafeWorkOffset = false; - operationNeedsSafeWorkPlane = false; - operationNeedsSafeCoolant = false; -} - -/** Output block to do safe retract and/or move to home position. */ -function writeRetract() { - // initialize routine - var _xyzMoved = new Array(false, false, false); - var _useG28 = properties.useG28; // can be either true or false - - // check syntax of call - if (arguments.length == 0) { - error(localize("No axis specified for writeRetract().")); - return; - } - for (var i = 0; i < arguments.length; ++i) { - if ((arguments[i] < 0) || (arguments[i] > 2)) { - error(localize("Bad axis specified for writeRetract().")); - return; - } - if (_xyzMoved[arguments[i]]) { - error(localize("Cannot retract the same axis twice in one line")); - return; - } - _xyzMoved[arguments[i]] = true; - } - - // special conditions - if (_useG28 && _xyzMoved[2] && (_xyzMoved[0] || _xyzMoved[1])) { // XY don't use G28 - error(localize("You cannot move home in XY & Z in the same block.")); - return; - } - if (_xyzMoved[0] || _xyzMoved[1]) { - _useG28 = false; - } - - // define home positions - var _xHome; - var _yHome; - var _zHome; - if (_useG28) { - _xHome = 0; - _yHome = 0; - _zHome = 0; - } else { - if (properties.homePositionCenter && - hasParameter("part-upper-x") && hasParameter("part-lower-x")) { - _xHome = (getParameter("part-upper-x") + getParameter("part-lower-x")) / 2; - } else { - _xHome = machineConfiguration.hasHomePositionX() ? machineConfiguration.getHomePositionX() : 0; - } - _yHome = machineConfiguration.hasHomePositionY() ? machineConfiguration.getHomePositionY() : 0; - _zHome = machineConfiguration.getRetractPlane(); - } - - // format home positions - var words = []; // store all retracted axes in an array - for (var i = 0; i < arguments.length; ++i) { - // define the axes to move - switch (arguments[i]) { - case X: - // special conditions - if (properties.homePositionCenter) { // output X in standard block by itself if centering - writeBlock(gMotionModal.format(0), xOutput.format(_xHome)); - _xyzMoved[0] = false; - break; - } - words.push("X" + xyzFormat.format(_xHome)); - break; - case Y: - words.push("Y" + xyzFormat.format(_yHome)); - break; - case Z: - words.push("Z" + xyzFormat.format(_zHome)); - retracted = true; - break; - } - } - - // output move to home - if (words.length > 0) { - if (_useG28) { - gAbsIncModal.reset(); - writeBlock(gFormat.format(28), gAbsIncModal.format(91), words); - writeBlock(gAbsIncModal.format(90)); - } else { - gMotionModal.reset(); - writeBlock(gAbsIncModal.format(90), gFormat.format(53), gMotionModal.format(0), words); - } - - // force any axes that move to home on next block - if (_xyzMoved[0]) { - xOutput.reset(); - } - if (_xyzMoved[1]) { - yOutput.reset(); - } - if (_xyzMoved[2]) { - zOutput.reset(); - } - } -} - -function onClose() { - writeln(""); - - optionalSection = false; - - onCommand(COMMAND_STOP_SPINDLE); - onCommand(COMMAND_COOLANT_OFF); - - // retract - writeRetract(Z); - - writeRetract(X, Y); - - if (activeG254) { - writeBlock(gFormat.format(255)); // cancel DWO - activeG254 = false; - } - - // MAY NEED CHANGE HOMING ORDER TO ROTARY THEN LINEAR FOR NON-UMC MACHINES - - // Unwind Rotary table at end - if (hasC) { - writeBlock(gFormat.format(28), gAbsIncModal.format(91), "C" + abcFormat.format(0)); - writeBlock(gAbsIncModal.format(90)); - } else if (hasB) { - writeBlock(gFormat.format(28), gAbsIncModal.format(91), "B" + abcFormat.format(0)); - writeBlock(gAbsIncModal.format(90)); - } else if (hasA) { - writeBlock(gFormat.format(28), gAbsIncModal.format(91), "A" + abcFormat.format(0)); - writeBlock(gAbsIncModal.format(90)); - } - - if (hasA || hasB || hasC) { - var abc = new Vector(0, 0, 0); - gMotionModal.reset(); - writeBlock( - gMotionModal.format(0), - conditional(machineConfiguration.isMachineCoordinate(0), "A" + abcFormat.format(abc.x)), - conditional(machineConfiguration.isMachineCoordinate(1), "B" + abcFormat.format(abc.y)), - conditional(machineConfiguration.isMachineCoordinate(2), "C" + abcFormat.format(abc.z)) - ); - } - - writeBlock(gRotationModal.format(69)); - onImpliedCommand(COMMAND_END); - onImpliedCommand(COMMAND_STOP_SPINDLE); - writeBlock(mFormat.format(30)); // stop program, spindle stop, coolant off - if (subprograms.length > 0) { - writeln(""); - write(subprograms); - } - writeln(""); - writeln("%"); -} - -/* -keywords += (keywords ? " MODEL_IMAGE" : "MODEL_IMAGE"); - -function onTerminate() { - var outputPath = getOutputPath(); - var programFilename = FileSystem.getFilename(outputPath); - var programSize = FileSystem.getFileSize(outputPath); - var postPath = findFile("setup-sheet-excel-2007.cps"); - var intermediatePath = getIntermediatePath(); - var a = "--property unit " + ((unit == IN) ? "0" : "1"); // use 0 for inch and 1 for mm - if (programName) { - a += " --property programName \"'" + programName + "'\""; - } - if (programComment) { - a += " --property programComment \"'" + programComment + "'\""; - } - a += " --property programFilename \"'" + programFilename + "'\""; - a += " --property programSize \"" + programSize + "\""; - a += " --noeditor --log temp.log \"" + postPath + "\" \"" + intermediatePath + "\" \"" + FileSystem.replaceExtension(outputPath, "xlsx") + "\""; - execute(getPostProcessorPath(), a, false, ""); - executeNoWait("excel", "\"" + FileSystem.replaceExtension(outputPath, "xlsx") + "\"", false, ""); -} -*/ diff --git a/Haas_Next_Generation/haas vf2.cps b/Haas_Next_Generation/haas vf2.cps index da684cb..4f2934f 100644 --- a/Haas_Next_Generation/haas vf2.cps +++ b/Haas_Next_Generation/haas vf2.cps @@ -1613,6 +1613,7 @@ function printProbeResults() { } var probeOutputWorkOffset = 1; +var stockTopZ = -1; function onPassThrough(text) { var commands = String(text).split(","); @@ -1645,6 +1646,12 @@ function onParameter(name, value) { if (name == "probe-output-work-offset") { probeOutputWorkOffset = (value > 0) ? value : 1; } + + // Added 6/15/21 | Gavin Williams | will1742 + // Issue 001 Input and Validation + if (name == "stock-upper-z") { + stockTopZ = value; + } } var seenPatternIds = {}; @@ -2020,6 +2027,10 @@ function onSection() { var initialPosition = getFramePosition(currentSection.getInitialPosition()); forceAny(); + // Added 06/15/21 | Gavin Williams | Will1742 + // + var onSecGotoRef = sequenceNumber; + if (operationNeedsSafeStart) { if (!retracted) { skipBlock = true; @@ -2332,9 +2343,24 @@ function onSection() { } } - displayMedia("testfile.png"); - takeInput("Y/N", ['Y', 'N']); - cancelMedia(); + // Added 06/15/21 | Gavin Williams | will1742 + // Verifies tool-stock distance. Post fails if tool fails clearance standards + var toolDistance = initialPosition.z - stockTopZ; + if (toolDistance < 1) { + throw "Error: Clearance height must be greater than 1 inch from stock"; + } + + if (toolDistance == Infinity) { + throw "Error: invalid tool distance. Contact a TA."; + } + // asks user if height is accurate + var gotoRef = takeInput(("Is the tool " + toolDistance.toPrecision(3) + "in from the stock? [Y/N]"), ['Y', 'N']); + + // if correct, carry on + writeln("N" + gotoRef[0][1] + " GOTO" + sequenceNumber); + + // if incorrect stop program and call for TA + getTA(gotoRef[1][1], onSecGotoRef); // Modified 06/09/21 | Gavin Williams | will1742 // Issue 000 Init coolant after positioning setCoolant(tool.coolant); @@ -2404,6 +2430,15 @@ function takeInput(prompt, options) { return gotoMap; } +// Added 06/15/21 | Gavin Williamas | will1742 +// Issue 001 Input and validation +// Halts program until TA arrives. Returns to beginning of onSection +function getTA(seqNum, gotoRef) { + writeln("N" + seqNum + " G53 G0 Z0."); + writeln("M02 (GET A TA)"); + writeln("GOTO" + gotoRef + " (Return to beginning of operation)"); +} + function onDwell(seconds) { if (seconds > 99999.999) { warning(localize("Dwelling time is out of range.")); From c070d392245a0ba8f60fa04ad6210e6429ea6ee2 Mon Sep 17 00:00:00 2001 From: will1742 Date: Tue, 15 Jun 2021 16:50:49 -0400 Subject: [PATCH 4/7] Fixed TA halting --- Haas_Next_Generation/haas vf2.cps | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Haas_Next_Generation/haas vf2.cps b/Haas_Next_Generation/haas vf2.cps index 4f2934f..bd86140 100644 --- a/Haas_Next_Generation/haas vf2.cps +++ b/Haas_Next_Generation/haas vf2.cps @@ -2435,8 +2435,8 @@ function takeInput(prompt, options) { // Halts program until TA arrives. Returns to beginning of onSection function getTA(seqNum, gotoRef) { writeln("N" + seqNum + " G53 G0 Z0."); - writeln("M02 (GET A TA)"); - writeln("GOTO" + gotoRef + " (Return to beginning of operation)"); + var conRef = takeInput("GET A TA", ['X']) + writeln("N" + conRef[0][1] + " GOTO" + gotoRef + " (Return to beginning of operation)"); } function onDwell(seconds) { From eb82fe139dade6732f8a3bb89da095279d53f306 Mon Sep 17 00:00:00 2001 From: will1742 Date: Fri, 18 Jun 2021 11:08:11 -0400 Subject: [PATCH 5/7] Streamlined Validation G Code --- Haas_Next_Generation/haas vf2.cps | 62 +++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/Haas_Next_Generation/haas vf2.cps b/Haas_Next_Generation/haas vf2.cps index bd86140..fb25d02 100644 --- a/Haas_Next_Generation/haas vf2.cps +++ b/Haas_Next_Generation/haas vf2.cps @@ -2037,6 +2037,11 @@ function onSection() { writeRetract(Z); } } + + // 6/18/21 | Gavin Williams | will1742 + // Terminate any media that may have been active at beginning of section + // Issue 001: Input and validation + cancelMedia(); if (insertToolCall || operationNeedsSafeStart) { @@ -2343,6 +2348,7 @@ function onSection() { } } + writeComment("BEGIN VALIDATION SECTION") // Added 06/15/21 | Gavin Williams | will1742 // Verifies tool-stock distance. Post fails if tool fails clearance standards var toolDistance = initialPosition.z - stockTopZ; @@ -2353,35 +2359,51 @@ function onSection() { if (toolDistance == Infinity) { throw "Error: invalid tool distance. Contact a TA."; } - // asks user if height is accurate - var gotoRef = takeInput(("Is the tool " + toolDistance.toPrecision(3) + "in from the stock? [Y/N]"), ['Y', 'N']); - // if correct, carry on - writeln("N" + gotoRef[0][1] + " GOTO" + sequenceNumber); + // Prompt user to check stock-tool distance + displayMedia("Net Share/checkDistance.png"); + + // Allow door to be opened + linePrint("M0" + " (Halt program)"); + displayMedia("Net Share/arrowDown.png"); + + // asks user if measured height is accurate to displayed + var gotoRef = takeInput(("Is the tool " + toolDistance.toPrecision(3) + "in from the stock? [Y/N]"), ['N', 'Y']); + + // Create GOTO cases for Y/N selection, halt if N + getTA("getTAWarning.png", gotoRef[0][1], onSecGotoRef); + + writeComment("END VALIDATION SECTION") + + // initialize spindle and engage coolant if heights are correct + writeln("N" + gotoRef[1][1] + " M" + (tool.clockwise ? 3 : 4) + " (Restart spindle)"); - // if incorrect stop program and call for TA - getTA(gotoRef[1][1], onSecGotoRef); // Modified 06/09/21 | Gavin Williams | will1742 // Issue 000 Init coolant after positioning setCoolant(tool.coolant); + // define subprogram subprogramDefine(initialPosition, abc, retracted, zIsOutput); } +// print with sequence number +function linePrint(message) { + writeln("N" + sequenceNumber + " " + message); + sequenceNumber += getProperty("sequenceNumberIncrement"); +} + // Added 6/14/21 | Gavin Williams | will1742 // Issue 001 Input and Validation // Displays a file: MP4, MOV, PNG, JPEG. 1920x1080 // Input: Absolute path to file function displayMedia(file) { - writeln("N" + sequenceNumber + " M130 (" + file + ")"); - sequenceNumber += getProperty("sequenceNumberIncrement"); + linePrint("M130 (" + file + ")"); } // Ends displayed media function cancelMedia() { - writeln("N" + sequenceNumber + " M131 (End Media)"); - sequenceNumber += getProperty("sequenceNumberIncrement"); + linePrint("M131" + " (End multimedia)"); } // Added 6/14/21 | Gavin Williams | will1742 @@ -2389,6 +2411,7 @@ function cancelMedia() { // Takes input from the user // Input: string prompt, will be displayed to users // char array options, capital letters accepted as input +// int opSeqNum, optional arg to init prompt at specific value // Output: 2D array [Letter, Coorresponding GOTO] // EX: [Y, 56][N, 57] var macroNumber = 500; @@ -2397,17 +2420,16 @@ function takeInput(prompt, options) { // Cycle through macro variables, reset at end of general purpose vars if (macroNumber > 549) macroNumber = 500; - // init var to 0 - writeln("#" + macroNumber + "=0"); + // init macro var to 0 + writeln("#" + macroNumber + "=0" + " (Initialize macro variable)"); // disply prompt and save response writeln("N" + sequenceNumber + " M109 " + "P" + macroNumber + " (" + prompt + ")"); var gotoRef = sequenceNumber; // wait for input - writeln("IF[#" + macroNumber + " EQ 0.] GOTO" + gotoRef) + writeln("IF[#" + macroNumber + " EQ 0.] GOTO" + gotoRef + " (NULL)"); - // TODO: Line number and GOTO optimization // print if's and goto's var gotoMap =[]; var gotoInc = 1; @@ -2417,12 +2439,13 @@ function takeInput(prompt, options) { gotoInc += 1; }); + // adjust sequence number if needed for (i = 5; i < gotoInc; i+=5) { sequenceNumber += getProperty("sequenceNumberIncrement"); } // return to input until valid option is entered - writeln("GOTO" + gotoRef) + writeln("GOTO" + gotoRef + " (INVALID INPUT)") // increase var number, iterate sequence number macroNumber += 1; @@ -2433,10 +2456,11 @@ function takeInput(prompt, options) { // Added 06/15/21 | Gavin Williamas | will1742 // Issue 001 Input and validation // Halts program until TA arrives. Returns to beginning of onSection -function getTA(seqNum, gotoRef) { - writeln("N" + seqNum + " G53 G0 Z0."); - var conRef = takeInput("GET A TA", ['X']) - writeln("N" + conRef[0][1] + " GOTO" + gotoRef + " (Return to beginning of operation)"); +function getTA(file, seqNum, gotoRef) { + writeln("N" + seqNum + " G53 G0 Z0." + " (Retract spindle)"); + writeln("M130 (" + file + ")"); + writeln("M0" + " (Halt program)"); + writeln("GOTO" + gotoRef + " (Return to beginning of operation)"); } function onDwell(seconds) { From a556a8d324880660ac3485f1679ac7cb961e66ce Mon Sep 17 00:00:00 2001 From: will1742 Date: Sun, 20 Jun 2021 14:54:05 -0400 Subject: [PATCH 6/7] Fixed settings and QA features --- Haas_Next_Generation/haas vf2.cps | 267 +++++++++++++++++------------- 1 file changed, 155 insertions(+), 112 deletions(-) diff --git a/Haas_Next_Generation/haas vf2.cps b/Haas_Next_Generation/haas vf2.cps index fb25d02..f5d022f 100644 --- a/Haas_Next_Generation/haas vf2.cps +++ b/Haas_Next_Generation/haas vf2.cps @@ -54,6 +54,7 @@ allowSpiralMoves = true; highFeedrate = 650 * 25.4; // must be in MM // user-defined properties +/* properties = { machineModel: { title: "Machine model", @@ -146,7 +147,7 @@ properties = { description: "Enable to turn on chip transport at start of program.", group: 2, type: "boolean", - value: false, + value: true, scope: "post" }, optionalStop: { @@ -178,7 +179,7 @@ properties = { description: "Parametric feed values based on movement type are output.", group: 2, type: "boolean", - value: false, + value: true, scope: "post" }, useG0: { @@ -186,7 +187,7 @@ properties = { description: "Specifies that G0s should be used for rapid moves when moving along a single axis.", group: 2, type: "boolean", - value: false, + value: true, scope: "post" }, safePositionMethod: { @@ -254,7 +255,7 @@ properties = { description: "Write optional blocks at the beginning of all operations that include all commands to start program.", group: 2, type: "boolean", - value: false, + value: true, scope: "post" }, fastToolChange: { @@ -292,7 +293,7 @@ properties = { {title: "Patterns", id: "patterns"} ], group: 3, - value: "none", + value: "allOperations", scope: "post" }, writeMachine: { @@ -356,7 +357,7 @@ properties = { description: "Enable to output notes for operations.", group: 4, type: "boolean", - value: false, + value: true, scope: "post" }, useM130PartImages: { @@ -398,6 +399,7 @@ properties = { scope: "post" } }; +*/ var singleLineCoolant = false; // specifies to output multiple coolant codes in one line rather than in separate lines // samples: @@ -415,6 +417,48 @@ var coolants = [ {id: COOLANT_OFF, off: 9} ]; +staticProperties = { +// TODO convert to single var + machineModel: "none", + safePositionMethod: "G53", + hasAAxis: "false", + hasBAxis: "false", + hasCAxis: "false", + useDPMFeeds: false, + useTCPC: true, + useDWO: true, + safeStartAllOperations: true, + preloadTool: true, + chipTransport: true, + optionalStop: true, + separateWordsWithSpace: true, + u1eRadius: false, + useParametricFeed: true, + useG0: true, + useG187: false, + homePositionCenter: false, + optionallyCycleToolsAtStart: false, + optionallyMeasureToolsAtStart: false, + forceHomeOnIndexing: true, + toolBreakageTolerance: 0.1, + fastToolChange: false, + useG95forTapping: false, + safeRetractDistance: 0, + useSubroutines: "allOperations", //allOperations + writeMachine: false, + writeTools: true, + writeVersion: false, + showSequenceNumbers: true, + sequenceNumberStart: 10, + sequenceNumberIncrement: 5, + sequenceNumberOnlyOnToolChange: false, + showNotes: true, + useM130PartImages: false, + useM130ToolImages: false, + coolantPressure: "", + singleResultsFile: true +}; + // old machines only support 4 digits var oFormat = createFormat({width:5, zeropad:true, decimals:0}); var nFormat = createFormat({decimals:0}); @@ -533,11 +577,11 @@ function writeBlock() { if (!text) { return; } - var maximumSequenceNumber = ((getProperty("useSubroutines") == "allOperations") || (getProperty("useSubroutines") == "patterns") || - (getProperty("useSubroutines") == "cycles")) ? initialSubprogramNumber : 99999; - if (getProperty("showSequenceNumbers")) { + var maximumSequenceNumber = ((staticProperties.useSubroutines == "allOperations") || (staticProperties.useSubroutines == "patterns") || + (staticProperties.useSubroutines == "cycles")) ? initialSubprogramNumber : 99999; + if (staticProperties.showSequenceNumbers) { if (sequenceNumber >= maximumSequenceNumber) { - sequenceNumber = getProperty("sequenceNumberStart"); + sequenceNumber = staticProperties.sequenceNumberStart; } if (optionalSection || skipBlock) { if (text) { @@ -546,7 +590,7 @@ function writeBlock() { } else { writeWords2("N" + sequenceNumber, arguments); } - sequenceNumber += getProperty("sequenceNumberIncrement"); + sequenceNumber += staticProperties.sequenceNumberIncrement; } else { if (optionalSection || skipBlock) { writeWords2("/", arguments); @@ -561,10 +605,10 @@ function writeBlock() { Writes the specified block - used for tool changes only. */ function writeToolBlock() { - var show = getProperty("showSequenceNumbers"); - setProperty("showSequenceNumbers", show || getProperty("sequenceNumberOnlyOnToolChange")); + var show = staticProperties.showSequenceNumbers; + staticProperties.showSequenceNumbers = (show || staticProperties.sequenceNumberOnlyOnToolChange); writeBlock(arguments); - setProperty("showSequenceNumbers", show); + staticProperties.showSequenceNumbers = show; } /** @@ -702,8 +746,8 @@ function writeToolMeasureBlock(tool, preMeasure) { } function defineMachineModel() { - var useTCPC = getProperty("useTCPC"); - switch (getProperty("machineModel")) { + var useTCPC = staticProperties.useTCPC; + switch (staticProperties.machineModel) { case "umc-500": var axis1 = createAxis({coordinate:1, table:true, axis:[0, 1, 0], range:[-35, 120], preference:1, tcp:useTCPC}); var axis2 = createAxis({coordinate:2, table:true, axis:[0, 0, 1], cyclic:true, preference:0, reset:1, tcp:useTCPC}); @@ -741,7 +785,7 @@ function defineMachineModel() { maximumSpindleRPM = 7500; break; } - machineConfiguration.setModel(getProperty("machineModel").toUpperCase()); + machineConfiguration.setModel(staticProperties.machineModel.toUpperCase()); machineConfiguration.setVendor("Haas Automation"); setMachineConfiguration(machineConfiguration); @@ -790,7 +834,7 @@ function activateMachine() { } // retract/reconfigure - safeRetractDistance = getProperty("safeRetractDistance") != undefined ? getProperty("safeRetractDistance") : + safeRetractDistance = staticProperties.singleResultsFile != undefined ? staticProperties.singleResultsFile : (typeof safeRetractDistance == "number" ? safeRetractDistance : 0); if (machineConfiguration.performRewinds() || (typeof performRewinds == "undefined" ? false : performRewinds)) { machineConfiguration.enableMachineRewinds(); // enables the rewind/reconfigure logic @@ -827,7 +871,7 @@ function setFeedrateMode(reset) { return; } machineConfiguration.setMultiAxisFeedrate( - tcpIsSupported ? FEED_FPM : getProperty("useDPMFeeds") ? FEED_DPM : FEED_INVERSE_TIME, + tcpIsSupported ? FEED_FPM : staticProperties.useDPMFeeds ? FEED_DPM : FEED_INVERSE_TIME, 9999.99, // maximum output value for inverse time feed rates INVERSE_MINUTES, // can be INVERSE_SECONDS or DPM_COMBINATION for DPM feeds 0.5, // tolerance to determine when the DPM feed has changed @@ -839,28 +883,28 @@ function setFeedrateMode(reset) { } function defineMachine() { - hasA = getProperty("hasAAxis") != "false"; - hasB = getProperty("hasBAxis") != "false"; - hasC = getProperty("hasCAxis") != "false"; + hasA = staticProperties.hasAAxis != "false"; + hasB = staticProperties.hasBAxis != "false"; + hasC = staticProperties.hasCAxis != "false"; if (hasA && hasB && hasC) { error(localize("Only two rotary axes can be active at the same time.")); return; - } else if ((hasA || hasB || hasC) && getProperty("machineModel") != "none") { + } else if ((hasA || hasB || hasC) && staticProperties.machineModel != "none") { error(localize("You can only select either a machine model or use the ABC axis properties.")); return; - } else if (((hasA || hasB || hasC) || getProperty("machineModel") != "none") && (receivedMachineConfiguration && machineConfiguration.isMultiAxisConfiguration())) { + } else if (((hasA || hasB || hasC) || staticProperties.machineModel != "none") && (receivedMachineConfiguration && machineConfiguration.isMultiAxisConfiguration())) { error(localize("You can only select either a machine in the CAM setup or use the properties to define your kinematics.")); return; } - if (getProperty("machineModel") == "none") { + if (staticProperties.machineModel == "none") { if (hasA || hasB || hasC) { // configure machine var aAxis; var bAxis; var cAxis; - var useTCPC = getProperty("useTCPC"); + var useTCPC = staticProperties.useTCPC; if (hasA) { // A Axis - For horizontal machines and trunnions - var dir = getProperty("hasAAxis") == "reversed" ? -1 : 1; + var dir = staticProperties.hasAAxis == "reversed" ? -1 : 1; if (hasC || hasB) { var aMin = (dir == 1) ? -120 - 0.0001 : -30 - 0.0001; var aMax = (dir == 1) ? 30 + 0.0001 : 120 + 0.0001; @@ -871,7 +915,7 @@ function defineMachine() { } if (hasB) { // B Axis - For horizontal machines and trunnions - var dir = getProperty("hasBAxis") == "reversed" ? -1 : 1; + var dir = staticProperties.hasBAxis == "reversed" ? -1 : 1; if (hasC) { var bMin = (dir == 1) ? -120 - 0.0001 : -30 - 0.0001; var bMax = (dir == 1) ? 30 + 0.0001 : 120 + 0.0001; @@ -884,7 +928,7 @@ function defineMachine() { } if (hasC) { // C Axis - For trunnions only - var dir = getProperty("hasCAxis") == "reversed" ? -1 : 1; + var dir = staticProperties.hasCAxis == "reversed" ? -1 : 1; cAxis = createAxis({coordinate:2, table:true, axis:[0, 0, dir], cyclic:true, reset:1, tcp:useTCPC}); } @@ -925,17 +969,17 @@ function onOpen() { } activateMachine(); // enable the machine optimizations and settings - if (getProperty("useDPMFeeds")) { + if (staticProperties.useDPMFeeds) { gFeedModeModal.format(94); } - if (getProperty("useRadius")) { + if (staticProperties.useRadius) { maximumCircularSweep = toRad(90); // avoid potential center calculation errors for CNC } - if (getProperty("sequenceNumberOnlyOnToolChange")) { - setProperty("showSequenceNumbers", false); + if (staticProperties.sequenceNumberOnlyOnToolChange) { + staticProperties.showSequenceNumbers = false; } - if (!getProperty("useDWO")) { - useDwoForPositioning = false; + if (!staticProperties.useDWO) { + useDWOForPositioning = false; } gRotationModal.format(69); // Default to G69 Rotation Off @@ -945,13 +989,12 @@ function onOpen() { return; } - if (!getProperty("separateWordsWithSpace")) { + if (!staticProperties.separateWordsWithSpace) { setWordSeparator(""); } - saveShowSequenceNumbers = getProperty("showSequenceNumbers"); - sequenceNumber = getProperty("sequenceNumberStart"); + saveshowSequenceNumbers = staticProperties.showSequenceNumbers; + sequenceNumber = staticProperties.sequenceNumberStart; writeln("%"); - if (programName) { var programId; try { @@ -974,13 +1017,13 @@ function onOpen() { return; } - if (getProperty("useG0")) { + if (staticProperties.useG0) { writeComment(localize("Using G0 which travels along dogleg path.")); } else { writeComment(subst(localize("Using high feed G1 F%1 instead of G0."), feedFormat.format(toPreciseUnit(highFeedrate, MM)))); } - if (getProperty("writeVersion")) { + if (staticProperties.writeVersion) { if ((typeof getHeaderVersion == "function") && getHeaderVersion()) { writeComment(localize("post version") + ": " + getHeaderVersion()); } @@ -994,7 +1037,7 @@ function onOpen() { var model = machineConfiguration.getModel(); var description = machineConfiguration.getDescription(); - if (getProperty("writeMachine") && (vendor || model || description)) { + if (staticProperties.writeMachine && (vendor || model || description)) { writeComment(localize("Machine")); if (vendor) { writeComment(" " + localize("vendor") + ": " + vendor); @@ -1008,7 +1051,7 @@ function onOpen() { } // dump tool information - if (getProperty("writeTools")) { + if (staticProperties.writeTools) { var zRanges = {}; if (is3D()) { var numberOfSections = getNumberOfSections(); @@ -1040,7 +1083,7 @@ function onOpen() { comment += " - " + getToolTypeName(tool.type); writeComment(comment); - if (getProperty("useM130ToolImages")) { + if (staticProperties.useM130PartImages) { var toolRenderer = createToolRenderer(); if (toolRenderer) { toolRenderer.setBackgroundColor(new Color(1, 1, 1)); @@ -1064,7 +1107,7 @@ function onOpen() { } // optionally cycle through all tools - if (getProperty("optionallyCycleToolsAtStart") || getProperty("optionallyMeasureToolsAtStart")) { + if (staticProperties.optionallyCycleToolsAtStart || staticProperties.optionallyMeasureToolsAtStart) { var tools = getToolTable(); if (tools.getNumberOfTools() > 0) { writeln(""); @@ -1072,14 +1115,14 @@ function onOpen() { writeOptionalBlock(mFormat.format(0), formatComment(localize("Read note"))); // wait for operator writeComment(localize("With BLOCK DELETE turned off each tool will cycle through")); writeComment(localize("the spindle to verify that the correct tool is in the tool magazine")); - if (getProperty("optionallyMeasureToolsAtStart")) { + if (staticProperties.optionallyMeasureToolsAtStart) { writeComment(localize("and to automatically measure it")); } writeComment(localize("Once the tools are verified turn BLOCK DELETE on to skip verification")); for (var i = 0; i < tools.getNumberOfTools(); ++i) { var tool = tools.getTool(i); - if (getProperty("optionallyMeasureToolsAtStart") && (tool.type == TOOL_PROBE)) { + if (staticProperties.optionallyMeasureToolsAtStart && (tool.type == TOOL_PROBE)) { continue; } var comment = "T" + toolFormat.format(tool.number) + " " + @@ -1090,7 +1133,7 @@ function onOpen() { } comment += " - " + getToolTypeName(tool.type); writeComment(comment); - if (getProperty("optionallyMeasureToolsAtStart")) { + if (staticProperties.optionallyMeasureToolsAtStart) { writeToolMeasureBlock(tool, true); } else { writeToolCycleBlock(tool); @@ -1100,7 +1143,7 @@ function onOpen() { writeln(""); } - if (false /*getProperty("useDWO")*/) { + if (false /*useDWO*/) { var failed = false; var dynamicWCSs = {}; for (var i = 0; i < getNumberOfSections(); ++i) { @@ -1176,9 +1219,9 @@ function onOpen() { break; } - coolantPressure = getProperty("coolantPressure"); + coolantPressure = staticProperties.coolantPressure; - if (getProperty("chipTransport")) { + if (staticProperties.chipTransport) { onCommand(COMMAND_START_CHIP_TRANSPORT); } // Probing Surface Inspection @@ -1504,7 +1547,7 @@ function setWorkPlane(abc) { skipBlock = _skipBlock; onCommand(COMMAND_LOCK_MULTI_AXIS); - if (getProperty("useDWO") && + if (staticProperties.useDWO && (abcFormat.isSignificant(abc.x % (Math.PI * 2)) || abcFormat.isSignificant(abc.y % (Math.PI * 2)) || abcFormat.isSignificant(abc.z % (Math.PI * 2)))) { skipBlock = _skipBlock; activeG254 = true; @@ -1686,7 +1729,7 @@ function previewImage() { warning(localize("The image file format " + "\"" + fileExtension + "\"" + " is not supported on HAAS controls.")); } - if (!getProperty("useM130PartImages") || !permittedExtension) { + if (!staticProperties.useM130PartImages || !permittedExtension) { FileSystem.remove(FileSystem.getCombinedPath(FileSystem.getFolderPath(getOutputPath()), images[i])); // remove images.splice([i], 1); // remove from array } @@ -1719,7 +1762,7 @@ function subprogramDefine(_initialPosition, _abc, _retracted, _zIsOutput) { // convert patterns into subprograms var usePattern = false; patternIsActive = false; - if (currentSection.isPatterned && currentSection.isPatterned() && (getProperty("useSubroutines") == "patterns")) { + if (currentSection.isPatterned && currentSection.isPatterned() && (staticProperties.useSubroutines == "patterns")) { currentPattern = currentSection.getPatternId(); firstPattern = true; for (var i = 0; i < definedPatterns.length; ++i) { @@ -1767,7 +1810,7 @@ function subprogramDefine(_initialPosition, _abc, _retracted, _zIsOutput) { } // Output cycle operation as subprogram - if (!usePattern && (getProperty("useSubroutines") == "cycles") && currentSection.doesStrictCycle && + if (!usePattern && (staticProperties.useSubroutines == "cycles") && currentSection.doesStrictCycle && (currentSection.getNumberOfCycles() == 1) && currentSection.getNumberOfCyclePoints() >= minimumCyclePoints) { var finalPosition = getFramePosition(currentSection.getFinalPosition()); currentPattern = currentSection.getNumberOfCyclePoints(); @@ -1802,7 +1845,7 @@ function subprogramDefine(_initialPosition, _abc, _retracted, _zIsOutput) { } // Output each operation as a subprogram - if (!usePattern && (getProperty("useSubroutines") == "allOperations")) { + if (!usePattern && (staticProperties.useSubroutines == "allOperations")) { currentSubprogram = ++lastSubprogram; writeBlock(mFormat.format(97), "P" + nFormat.format(currentSubprogram)); firstPattern = true; @@ -1820,7 +1863,7 @@ function subprogramStart(_initialPosition, _abc, _incremental) { "N" + nFormat.format(currentSubprogram) + conditional(comment, formatComment(comment.substr(0, maximumLineLength - 2 - 6 - 1))) ); - setProperty("showSequenceNumbers", false); + staticProperties.showSequenceNumbers = false; if (_incremental) { setIncrementalMode(_initialPosition, _abc); } @@ -1836,7 +1879,7 @@ function subprogramEnd() { } forceAny(); firstPattern = false; - setProperty("showSequenceNumbers", saveShowSequenceNumbers); + staticProperties.showSequenceNumbers = saveshowSequenceNumbers; closeRedirection(); } @@ -1960,20 +2003,20 @@ function onSection() { (!getPreviousSection().isMultiAxis() && currentSection.isMultiAxis() || getPreviousSection().isMultiAxis() && !currentSection.isMultiAxis()); // force newWorkPlane between indexing and simultaneous operations - operationNeedsSafeStart = getProperty("safeStartAllOperations") && !isFirstSection(); + operationNeedsSafeStart = staticProperties.safeStartAllOperations && !isFirstSection(); if (insertToolCall || operationNeedsSafeStart) { - if (getProperty("fastToolChange") && !isProbeOperation()) { + if (staticProperties.fastToolChange && !isProbeOperation()) { currentCoolantMode = COOLANT_OFF; } else if (insertToolCall) { // no coolant off command if safe start operation onCommand(COMMAND_COOLANT_OFF); } } - if ((insertToolCall && !getProperty("fastToolChange")) || newWorkOffset || newWorkPlane || toolChecked) { + if ((insertToolCall && !staticProperties.fastToolChange) || newWorkOffset || newWorkPlane || toolChecked) { // stop spindle before retract during tool change - if (insertToolCall && !isFirstSection() && !toolChecked && !getProperty("fastToolChange")) { + if (insertToolCall && !isFirstSection() && !toolChecked && !staticProperties.fastToolChange) { onCommand(COMMAND_STOP_SPINDLE); } @@ -1999,7 +2042,7 @@ function onSection() { writeln(""); } - if (getProperty("showNotes") && hasParameter("notes")) { + if (staticProperties.showNotes && hasParameter("notes")) { var notes = getParameter("notes"); if (notes) { var lines = String(notes).split("\n"); @@ -2033,7 +2076,7 @@ function onSection() { if (operationNeedsSafeStart) { if (!retracted) { - skipBlock = true; + // skipBlock = true; writeRetract(Z); } } @@ -2045,11 +2088,11 @@ function onSection() { if (insertToolCall || operationNeedsSafeStart) { - if (getProperty("useM130ToolImages")) { + if (staticProperties.useM130PartImages) { writeBlock(mFormat.format(130), "(tool" + tool.number + ".png)"); } - if (!isFirstSection() && getProperty("optionalStop") && insertToolCall) { + if (!isFirstSection() && staticProperties.optionalStop && insertToolCall) { onCommand(COMMAND_OPTIONAL_STOP); } @@ -2121,7 +2164,7 @@ function onSection() { if (spindleSpeed > maximumSpindleRPM) { warning(subst(localize("Spindle speed '" + spindleSpeed + " RPM' exceeds maximum value of '%1 RPM."), maximumSpindleRPM)); } - skipBlock = !spindleChanged; + // skipBlock = !spindleChanged; writeBlock( sOutput.format(spindleSpeed), mFormat.format(tool.clockwise ? 3 : 4) ); @@ -2129,7 +2172,7 @@ function onSection() { previewImage(); - if (getProperty("useParametricFeed") && + if (staticProperties.useParametricFeed && hasParameter("operation-strategy") && (getParameter("operation-strategy") != "drill") && // legacy !(currentSection.hasAnyCycle && currentSection.hasAnyCycle())) { @@ -2184,7 +2227,7 @@ function onSection() { if (!retracted) { writeRetract(Z); } - if (getProperty("forceHomeOnIndexing") && machineConfiguration.isMultiAxisConfiguration()) { + if (staticProperties.forceHomeOnIndexing && machineConfiguration.isMultiAxisConfiguration()) { writeRetract(X, Y); } } @@ -2209,12 +2252,12 @@ function onSection() { gMotionModal.reset(); - if (getProperty("useG187")) { + if (staticProperties.useG187) { writeG187(); } - var G = ((highFeedMapping != HIGH_FEED_NO_MAPPING) || !getProperty("useG0")) ? 1 : 0; - var F = ((highFeedMapping != HIGH_FEED_NO_MAPPING) || !getProperty("useG0")) ? getFeed(toPreciseUnit(highFeedrate, MM)) : ""; + var G = ((highFeedMapping != HIGH_FEED_NO_MAPPING) || !staticProperties.useG0) ? 1 : 0; + var F = ((highFeedMapping != HIGH_FEED_NO_MAPPING) || !staticProperties.useG0) ? getFeed(toPreciseUnit(highFeedrate, MM)) : ""; if (insertToolCall || retracted || operationNeedsSafeStart || !lengthCompensationActive || (!isFirstSection() && (currentSection.isMultiAxis() != getPreviousSection().isMultiAxis()))) { var _skipBlock = !(insertToolCall || retracted || @@ -2319,7 +2362,7 @@ function onSection() { validate(lengthCompensationActive, "Length compensation is not active."); if (insertToolCall || operationNeedsSafeStart) { - if (getProperty("preloadTool")) { + if (staticProperties.preloadTool) { var nextTool = getNextTool(tool.number); if (nextTool) { skipBlock = !insertToolCall; @@ -2361,23 +2404,23 @@ function onSection() { } // Prompt user to check stock-tool distance - displayMedia("Net Share/checkDistance.png"); + displayMedia("Net Share/Media/checkDistance.png"); // Allow door to be opened linePrint("M0" + " (Halt program)"); - displayMedia("Net Share/arrowDown.png"); + displayMedia("Net Share/Media/arrowDown.png"); // asks user if measured height is accurate to displayed var gotoRef = takeInput(("Is the tool " + toolDistance.toPrecision(3) + "in from the stock? [Y/N]"), ['N', 'Y']); // Create GOTO cases for Y/N selection, halt if N - getTA("getTAWarning.png", gotoRef[0][1], onSecGotoRef); + getTA("Net Share/Media/TAWarning.png", gotoRef[0][1], onSecGotoRef); writeComment("END VALIDATION SECTION") - // initialize spindle and engage coolant if heights are correct - writeln("N" + gotoRef[1][1] + " M" + (tool.clockwise ? 3 : 4) + " (Restart spindle)"); - + writeln("N" + gotoRef[1][1] + " M131 (End Multimedia)"); + linePrint("M" + (tool.clockwise ? 3 : 4) + " (Restart spindle)"); + // Modified 06/09/21 | Gavin Williams | will1742 // Issue 000 Init coolant after positioning setCoolant(tool.coolant); @@ -2390,7 +2433,7 @@ function onSection() { // print with sequence number function linePrint(message) { writeln("N" + sequenceNumber + " " + message); - sequenceNumber += getProperty("sequenceNumberIncrement"); + sequenceNumber += staticProperties.sequenceNumberIncrement; } // Added 6/14/21 | Gavin Williams | will1742 @@ -2441,7 +2484,7 @@ function takeInput(prompt, options) { // adjust sequence number if needed for (i = 5; i < gotoInc; i+=5) { - sequenceNumber += getProperty("sequenceNumberIncrement"); + sequenceNumber += staticProperties.sequenceNumberIncrement; } // return to input until valid option is entered @@ -2449,7 +2492,7 @@ function takeInput(prompt, options) { // increase var number, iterate sequence number macroNumber += 1; - sequenceNumber += getProperty("sequenceNumberIncrement"); + sequenceNumber += staticProperties.sequenceNumberIncrement; return gotoMap; } @@ -2617,7 +2660,7 @@ function onCyclePoint(x, y, z) { if (!allowIndexingWCSProbing && currentSection.strategy == "probe") { error(localize("Updating WCS / work offset using probing is only supported by the CNC in the WCS frame.")); return; - } else if (getProperty("useDWO")) { + } else if (staticProperties.useDWO) { error(localize("Your machine does not support the selected probing operation with DWO enabled.")); return; } @@ -2714,8 +2757,8 @@ function onCyclePoint(x, y, z) { break; case "tapping": var tappingFPM = tool.getThreadPitch() * rpmFormat.getResultingValue(spindleSpeed); - F = (getProperty("useG95forTapping") ? tool.getThreadPitch() : tappingFPM); - if (getProperty("useG95forTapping")) { + F = (staticProperties.useG95forTapping ? tool.getThreadPitch() : tappingFPM); + if (staticProperties.useG95forTapping) { writeBlock(gFeedModeModal.format(95)); } writeBlock( @@ -2727,8 +2770,8 @@ function onCyclePoint(x, y, z) { break; case "left-tapping": var tappingFPM = tool.getThreadPitch() * rpmFormat.getResultingValue(spindleSpeed); - F = (getProperty("useG95forTapping") ? tool.getThreadPitch() : tappingFPM); - if (getProperty("useG95forTapping")) { + F = (staticProperties.useG95forTapping ? tool.getThreadPitch() : tappingFPM); + if (staticProperties.useG95forTapping) { writeBlock(gFeedModeModal.format(95)); } writeBlock( @@ -2740,8 +2783,8 @@ function onCyclePoint(x, y, z) { break; case "right-tapping": var tappingFPM = tool.getThreadPitch() * rpmFormat.getResultingValue(spindleSpeed); - F = (getProperty("useG95forTapping") ? tool.getThreadPitch() : tappingFPM); - if (getProperty("useG95forTapping")) { + F = (staticProperties.useG95forTapping ? tool.getThreadPitch() : tappingFPM); + if (staticProperties.useG95forTapping) { writeBlock(gFeedModeModal.format(95)); } writeBlock( @@ -2755,8 +2798,8 @@ function onCyclePoint(x, y, z) { case "left-tapping-with-chip-breaking": case "right-tapping-with-chip-breaking": var tappingFPM = tool.getThreadPitch() * rpmFormat.getResultingValue(spindleSpeed); - F = (getProperty("useG95forTapping") ? tool.getThreadPitch() : tappingFPM); - if (getProperty("useG95forTapping")) { + F = (staticProperties.useG95forTapping ? tool.getThreadPitch() : tappingFPM); + if (staticProperties.useG95forTapping) { writeBlock(gFeedModeModal.format(95)); } // Parameter 57 bit 6, REPT RIG TAP, is set to 1 (On) @@ -3291,7 +3334,7 @@ function onCycleEnd() { cycleSubprogramIsActive = false; } if (!cycleExpanded) { - writeBlock(gCycleModal.format(80), conditional(getProperty("useG95forTapping"), gFeedModeModal.format(94))); + writeBlock(gCycleModal.format(80), conditional(staticProperties.useG95forTapping, gFeedModeModal.format(94))); gMotionModal.reset(); } } @@ -3313,7 +3356,7 @@ function onRapid(_x, _y, _z) { error(localize("Radius compensation mode cannot be changed at rapid traversal.")); return; } - if (!getProperty("useG0") && !forceG0 && (((x ? 1 : 0) + (y ? 1 : 0) + (z ? 1 : 0)) > 1)) { + if (!staticProperties.useG0 && !forceG0 && (((x ? 1 : 0) + (y ? 1 : 0) + (z ? 1 : 0)) > 1)) { // axes are not synchronized writeBlock(gFeedModeModal.format(94), gMotionModal.format(1), x, y, z, getFeed(toPreciseUnit(highFeedrate, MM))); } else { @@ -3383,7 +3426,7 @@ function onRapid5D(_x, _y, _z, _a, _b, _c) { ((aOutput.isEnabled() && abcFormat.areDifferent(_a, aOutput.getCurrent())) ? 1 : 0) + ((bOutput.isEnabled() && abcFormat.areDifferent(_b, bOutput.getCurrent())) ? 1 : 0) + ((cOutput.isEnabled() && abcFormat.areDifferent(_c, cOutput.getCurrent())) ? 1 : 0); - if (!getProperty("useG0") && !forceG0 && (tcpIsSupported || (num > 1))) { + if (!staticProperties.useG0 && !forceG0 && (tcpIsSupported || (num > 1))) { invokeOnLinear5D(_x, _y, _z, _a, _b, _c, toPreciseUnit(highFeedrate, MM)); // onLinear5D handles inverse time feedrates return; } @@ -3441,7 +3484,7 @@ function moveToSafeRetractPosition(isRetracted) { if (!isRetracted) { writeRetract(Z); } - if (getProperty("forceHomeOnIndexing")) { + if (staticProperties.forceHomeOnIndexing) { skipBlock = _skipBlock; writeRetract(X, Y); } @@ -3580,7 +3623,7 @@ function onCircular(clockwise, cx, cy, cz, x, y, z, feed) { var start = getCurrentPosition(); if (isFullCircle()) { - if (getProperty("useRadius") || isHelical()) { // radius mode does not support full arcs + if (staticProperties.useRadius || isHelical()) { // radius mode does not support full arcs linearize(tolerance); return; } @@ -3597,7 +3640,7 @@ function onCircular(clockwise, cx, cy, cz, x, y, z, feed) { default: linearize(tolerance); } - } else if (!getProperty("useRadius")) { + } else if (!staticProperties.useRadius) { switch (getCircularPlane()) { case PLANE_XY: writeBlock(gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), getFeed(feed)); @@ -3673,7 +3716,7 @@ function getCoolantCodes(coolant) { } if (coolant == currentCoolantMode) { if (operationNeedsSafeStart && coolant != COOLANT_OFF && !isSpecialCoolantActive) { - isOptionalCoolant = true; + // isOptionalCoolant = true; } else if (!forceCoolant || coolant == COOLANT_OFF) { return undefined; // coolant is already active } @@ -3794,7 +3837,7 @@ function onCommand(command) { "P" + 9853, "T" + toolFormat.format(tool.number), "B" + xyzFormat.format(0), - "H" + xyzFormat.format(getProperty("toolBreakageTolerance")) + "H" + xyzFormat.format(staticProperties.toolBreakageTolerance) ); toolChecked = true; lengthCompensationActive = false; // macro 9853 cancels tool length compensation @@ -3881,7 +3924,7 @@ function onSectionEnd() { // reset for next section operationNeedsSafeStart = false; - coolantPressure = getProperty("coolantPressure"); + coolantPressure = staticProperties.coolantPressure; cycleReverse = false; setPolarMode(currentSection, false); @@ -3891,7 +3934,7 @@ function onSectionEnd() { function writeRetract() { var words = []; // store all retracted axes in an array var retractAxes = new Array(false, false, false); - var method = getProperty("safePositionMethod"); + var method = staticProperties.safePositionMethod; if (method == "clearanceHeight") { if (!is3D()) { error(localize("Retract option 'Clearance Height' is not supported for multi-axis machining.")); @@ -3980,7 +4023,7 @@ function writeRetract() { var isDPRNTopen = false; function inspectionCreateResultsFileHeader() { if (isDPRNTopen) { - if (!getProperty("singleResultsFile")) { + if (!staticProperties.singleResultsFile) { writeln("DPRNT[END]"); writeBlock("PCLOS"); isDPRNTopen = false; @@ -3996,7 +4039,7 @@ function inspectionCreateResultsFileHeader() { writeBlock("POPEN"); // check for existence of none alphanumeric characters but not spaces var resFile; - if (getProperty("singleResultsFile")) { + if (staticProperties.singleResultsFile) { resFile = getParameter("job-description") + "-RESULTS"; } else { resFile = getParameter("operation-comment") + "-RESULTS"; @@ -4083,7 +4126,7 @@ function onClose() { // retract writeRetract(Z); - if (!getProperty("homePositionCenter") || currentMachineABC.length != 0) { + if (!staticProperties.homePositionCenter || currentMachineABC.length != 0) { writeRetract(X, Y); } @@ -4115,15 +4158,15 @@ function onClose() { conditional(machineConfiguration.isMachineCoordinate(2), "C" + abcFormat.format(0)) ); } - if (getProperty("homePositionCenter")) { - homePositionCenter = getProperty("homePositionCenter"); + if (staticProperties.homePositionCenter) { + homePositionCenter = staticProperties.homePositionCenter; writeRetract(X, Y); } onImpliedCommand(COMMAND_END); onImpliedCommand(COMMAND_STOP_SPINDLE); - if (getProperty("useM130PartImages") || getProperty("useM130ToolImages")) { + if (staticProperties.useM130PartImages || staticProperties.useM130ToolImages) { writeBlock(mFormat.format(131)); } writeBlock(mFormat.format(30)); // stop program, spindle stop, coolant off @@ -4809,20 +4852,20 @@ function inspectionWriteMeasuredData() { function forceSequenceNumbers(force) { if (force) { - setProperty("showSequenceNumbers", true); + staticProperties.showSequenceNumbers = true; } else { - setProperty("showSequenceNumbers", saveShowSequenceNumbers); + staticProperties.showSequenceNumbers = saveshowSequenceNumbers; } } function skipNLines(n) { - return (n * getProperty("sequenceNumberIncrement") + sequenceNumber); + return (n * staticProperties.sequenceNumberIncrement + sequenceNumber); } function inspectionProcessSectionStart() { writeBlock(gFormat.format(103), "P1", formatComment("LOOKAHEAD OFF")); // only write header once if user selects a single results file - if (!isDPRNTopen || !getProperty("singleResultsFile") || (currentSection.workOffset != inspectionVariables.workpieceOffset)) { + if (!isDPRNTopen || !staticProperties.singleResultsFile || (currentSection.workOffset != inspectionVariables.workpieceOffset)) { inspectionCreateResultsFileHeader(); inspectionVariables.workpieceOffset = currentSection.workOffset; } @@ -4895,7 +4938,7 @@ function inspectionProcessSectionEnd() { if (getProperty("commissioningMode")) { if (controlType == "NGC") { forceSequenceNumbers(true); - writeBlock(inspectionVariables.macroVariable1 + " = [#20261 * " + 4 * getProperty("sequenceNumberIncrement") + " + " + skipNLines(2) + "]"); + writeBlock(inspectionVariables.macroVariable1 + " = [#20261 * " + 4 * staticProperties.sequenceNumberIncrement + " + " + skipNLines(2) + "]"); writeBlock("GOTO " + inspectionVariables.macroVariable1); writeBlock(" "); writeBlock("#3006=1" + formatComment("DPRNT LOCATION NOT SET")); From 4bbc94dd1ff1a4f25f87f05095c154d72d5bc6d1 Mon Sep 17 00:00:00 2001 From: will1742 Date: Mon, 21 Jun 2021 16:53:40 -0400 Subject: [PATCH 7/7] added tool probing, cleaned code --- .gitignore | 2 + Haas_Next_Generation/haas vf2.cps | 83 +++++++++++++++++-------------- 2 files changed, 49 insertions(+), 36 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e45abea --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ + +Old/haas next generation.cps diff --git a/Haas_Next_Generation/haas vf2.cps b/Haas_Next_Generation/haas vf2.cps index f5d022f..507b1c1 100644 --- a/Haas_Next_Generation/haas vf2.cps +++ b/Haas_Next_Generation/haas vf2.cps @@ -226,7 +226,7 @@ properties = { value: false, scope: "post" }, - optionallyMeasureToolsAtStart: { + measureToolsAtStart: { title: "Optionally measure tools at start", description: "Measure each tool used at the beginning of the program when block delete is turned off.", group: 2, @@ -438,7 +438,7 @@ staticProperties = { useG187: false, homePositionCenter: false, optionallyCycleToolsAtStart: false, - optionallyMeasureToolsAtStart: false, + measureToolsAtStart: true, forceHomeOnIndexing: true, toolBreakageTolerance: 0.1, fastToolChange: false, @@ -709,13 +709,14 @@ function prepareForToolCheck() { } function writeToolMeasureBlock(tool, preMeasure) { - var writeFunction = measureTool ? writeBlock : writeOptionalBlock; + // var writeFunction = measureTool ? writeBlock : writeOptionalBlock; + var writeFunction = writeBlock; var comment = measureTool ? formatComment("MEASURE TOOL") : ""; if (!preMeasure) { prepareForToolCheck(); } - if (true) { // use Macro P9023 to measure tools + if (false) { // use Macro P9023 to measure tools var probingType = getHaasProbingType(tool.type, true); writeFunction( gFormat.format(65), @@ -727,7 +728,7 @@ function writeToolMeasureBlock(tool, preMeasure) { comment ); } else { // use Macro P9995 to measure tools - writeFunction("T" + toolFormat.format(tool.number), mFormat.format(6)); // get tool + // writeFunction("T" + toolFormat.format(tool.number), mFormat.format(6)); // get tool writeFunction( gFormat.format(65), "P9995", @@ -1106,23 +1107,36 @@ function onOpen() { } } + // 6/21/21 | Gavin Williams | will1742 + // Probing now required. Using P9995. + // optionally cycle through all tools - if (staticProperties.optionallyCycleToolsAtStart || staticProperties.optionallyMeasureToolsAtStart) { + if (staticProperties.optionallyCycleToolsAtStart || staticProperties.measureToolsAtStart) { var tools = getToolTable(); if (tools.getNumberOfTools() > 0) { writeln(""); - + /* writeOptionalBlock(mFormat.format(0), formatComment(localize("Read note"))); // wait for operator writeComment(localize("With BLOCK DELETE turned off each tool will cycle through")); writeComment(localize("the spindle to verify that the correct tool is in the tool magazine")); - if (staticProperties.optionallyMeasureToolsAtStart) { + if (staticProperties.measureToolsAtStart) { writeComment(localize("and to automatically measure it")); } writeComment(localize("Once the tools are verified turn BLOCK DELETE on to skip verification")); - + */ + + // 6/21/21 | Gavin Williams | will1742 + writeBlock(gFormat.format(0), + gFormat.format(17), + gFormat.format(40), + gFormat.format(49), + gFormat.format(80), + gFormat.format(90), formatComment("Reset work plane, cancel all cycles and offsets")); + writeComment("Load and probe tools"); + for (var i = 0; i < tools.getNumberOfTools(); ++i) { var tool = tools.getTool(i); - if (staticProperties.optionallyMeasureToolsAtStart && (tool.type == TOOL_PROBE)) { + if (staticProperties.measureToolsAtStart && (tool.type == TOOL_PROBE)) { continue; } var comment = "T" + toolFormat.format(tool.number) + " " + @@ -1133,7 +1147,10 @@ function onOpen() { } comment += " - " + getToolTypeName(tool.type); writeComment(comment); - if (staticProperties.optionallyMeasureToolsAtStart) { + if (staticProperties.measureToolsAtStart) { + writeBlock("T" + toolFormat.format(tool.number), mFormat.format(6)); //Changes Tool + writeBlock(mFormat.format(0), formatComment("Load Tool")); //Pause until operator loads tool + //writeToolMeasureOPT(tool); writeToolMeasureBlock(tool, true); } else { writeToolCycleBlock(tool); @@ -1143,7 +1160,7 @@ function onOpen() { writeln(""); } - if (false /*useDWO*/) { + if (staticProperties.useDWO) { var failed = false; var dynamicWCSs = {}; for (var i = 0; i < getNumberOfSections(); ++i) { @@ -2084,7 +2101,7 @@ function onSection() { // 6/18/21 | Gavin Williams | will1742 // Terminate any media that may have been active at beginning of section // Issue 001: Input and validation - cancelMedia(); + writeBlock(mFormat.format(131), formatComment("End multimedia")); if (insertToolCall || operationNeedsSafeStart) { @@ -2407,7 +2424,7 @@ function onSection() { displayMedia("Net Share/Media/checkDistance.png"); // Allow door to be opened - linePrint("M0" + " (Halt program)"); + writeBlock(mFormat.format(0), formatComment("Open door")); displayMedia("Net Share/Media/arrowDown.png"); // asks user if measured height is accurate to displayed @@ -2418,8 +2435,8 @@ function onSection() { writeComment("END VALIDATION SECTION") // initialize spindle and engage coolant if heights are correct - writeln("N" + gotoRef[1][1] + " M131 (End Multimedia)"); - linePrint("M" + (tool.clockwise ? 3 : 4) + " (Restart spindle)"); + writeln("N" + nFormat.format(gotoRef[1][1]) + " " + mFormat.format(131) + " " + formatComment("End Multimedia")); + writeBlock(mFormat.format((tool.clockwise ? 3 : 4)), formatComment("Restart spindle")); // Modified 06/09/21 | Gavin Williams | will1742 // Issue 000 Init coolant after positioning @@ -2430,25 +2447,17 @@ function onSection() { subprogramDefine(initialPosition, abc, retracted, zIsOutput); } -// print with sequence number -function linePrint(message) { - writeln("N" + sequenceNumber + " " + message); - sequenceNumber += staticProperties.sequenceNumberIncrement; -} - // Added 6/14/21 | Gavin Williams | will1742 // Issue 001 Input and Validation // Displays a file: MP4, MOV, PNG, JPEG. 1920x1080 // Input: Absolute path to file function displayMedia(file) { - linePrint("M130 (" + file + ")"); + writeBlock(mFormat.format(130), formatComment(file)); } // Ends displayed media -function cancelMedia() { - linePrint("M131" + " (End multimedia)"); -} +// TODO: switch to map for gotoref // Added 6/14/21 | Gavin Williams | will1742 // Issue 001 Input and Validation // Takes input from the user @@ -2464,20 +2473,20 @@ function takeInput(prompt, options) { if (macroNumber > 549) macroNumber = 500; // init macro var to 0 - writeln("#" + macroNumber + "=0" + " (Initialize macro variable)"); + writeln("#" + macroNumber + "=0" + " " + formatComment("Initialize macro variable")); // disply prompt and save response - writeln("N" + sequenceNumber + " M109 " + "P" + macroNumber + " (" + prompt + ")"); - var gotoRef = sequenceNumber; + writeBlock(mFormat.format(109), "P" + nFormat.format(macroNumber), formatComment(prompt)); + var gotoRef = sequenceNumber - staticProperties.sequenceNumberIncrement; // wait for input - writeln("IF[#" + macroNumber + " EQ 0.] GOTO" + gotoRef + " (NULL)"); + writeln("IF[#" + macroNumber + " EQ 0.] GOTO" + nFormat.format(gotoRef) + " " + formatComment("NULL")); // print if's and goto's var gotoMap =[]; var gotoInc = 1; options.forEach(function (element) { - writeln("IF[#" + macroNumber + " EQ " + element.charCodeAt(0) + ".] GOTO" + (sequenceNumber + gotoInc) + " (" + element + ")"); + writeln("IF[#" + macroNumber + " EQ " + element.charCodeAt(0) + ".] GOTO" + nFormat.format(sequenceNumber + gotoInc) + " (" + element + ")"); gotoMap.push([element, (sequenceNumber + gotoInc)]); gotoInc += 1; }); @@ -2488,7 +2497,7 @@ function takeInput(prompt, options) { } // return to input until valid option is entered - writeln("GOTO" + gotoRef + " (INVALID INPUT)") + writeln("GOTO" + nFormat.format(gotoRef) + " " + formatComment("INVALID INPUT")) // increase var number, iterate sequence number macroNumber += 1; @@ -2500,10 +2509,12 @@ function takeInput(prompt, options) { // Issue 001 Input and validation // Halts program until TA arrives. Returns to beginning of onSection function getTA(file, seqNum, gotoRef) { - writeln("N" + seqNum + " G53 G0 Z0." + " (Retract spindle)"); - writeln("M130 (" + file + ")"); - writeln("M0" + " (Halt program)"); - writeln("GOTO" + gotoRef + " (Return to beginning of operation)"); + writeln("N" + nFormat.format(seqNum) + " " + + gFormat.format(53) + " " + gFormat.format(0) + " " + zOutput.format(0.) + " " + + formatComment("Retract spindle")); + writeln(mFormat.format(130) + " " + formatComment(file)); + writeln(mFormat.format(0) + " " + formatComment("Halt Program")); + writeln("GOTO" + nFormat.format(gotoRef) + " " + formatComment("Return to beginning of operation")); } function onDwell(seconds) {