/** Copyright (C) 2012-2021 by Autodesk, Inc. All rights reserved. Roeders post processor configuration. $Revision: 44083 1c5ad993a086f043365c6f9038d5d6561bad0ddd $ $Date: 2023-08-12 05:06:32 $ FORKID {52AF2F8D-9534-472E-BE65-93BD6D56FCBF} */ description = "Roeders"; vendor = "Roeders"; vendorUrl = "https://www.roeders.de/"; legal = "Copyright (C) 2012-2021 by Autodesk, Inc."; certificationLevel = 2; minimumRevision = 45702; longDescription = "Generic post for Roeders with RMS6 control version 5.52 or higher." + EOL + "This postprocessor has advanced features like subprogram support and is prepared for full 5 axis machining."; extension = "BEF"; if (getCodePage() == 932) { // shift-jis is not supported setCodePage("ascii"); } else { setCodePage("ansi"); // setCodePage("utf-8"); } 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(180); allowHelicalMoves = false; allowedCircularPlanes = undefined; // allow any circular motion highFeedrate = (unit == IN) ? 393 : 10000; // user-defined properties properties = { writeMachine: { title : "Write machine", description: "Output the machine settings in the header of the code.", group : "formats", type : "boolean", value : false, scope : "post" }, writeTools: { title : "Write tool list", description: "Output a tool list in the header of the code.", group : "formats", type : "boolean", value : true, scope : "post" }, preloadTool: { title : "Tool Look Ahead", description: "Look ahead for tools when using tool names.", group : "preferences", type : "boolean", value : false, scope : "post" }, measureTools: { title : "Measure tools", description: "Specifies the desired option for tool measuring.", group : "preferences", type : "enum", values : [ {title:"Disabled", id:"disabled"}, {title:"At start", id:"start"}, {title:"At start and end", id:"startEnd"} ], value: "disabled", scope: "post" }, writeVersion: { title : "Write version", description: "Write the version number in the header of the code.", group : "formats", type : "boolean", value : false, scope : "post" }, expandCycles: { title : "Expand cycles", description: "If enabled, unhandled cycles are expanded.", group : "preferences", type : "boolean", value : true, scope : "post" }, showSequenceNumbers: { title : "Use sequence numbers", description: "'Yes' outputs sequence numbers on each block, 'Only on tool change' outputs sequence numbers on tool change blocks only, and 'No' disables the output of sequence numbers.", group : "formats", type : "enum", values : [ {title:"Yes", id:"true"}, {title:"No", id:"false"}, {title:"Only on tool change", id:"toolChange"} ], value: "false", 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.", group : "preferences", type : "enum", values : [ {title:"No", id:"none"}, {title:"All Operations", id:"allOperations"}, {title:"Cycles", id:"cycles"}, {title:"Patterns", id:"patterns"} ], value: "none", scope: "post" }, useFilesForSubprograms: { title : "Use files for subroutines", description: "If enabled, subroutines will be saved as individual files.", group : "preferences", type : "boolean", value : false, scope : "post" }, allowArcs: { title : "Allow arcs", description: "If disabled, all arcs will be linearized (recommended).", group : "preferences", type : "boolean", value : false, scope : "post" }, useParametricFeed: { title : "Parametric feed", description: "Specifies the feed value that should be output using a Q value.", group : "preferences", type : "boolean", value : false, scope : "post" }, toolAsName: { title : "Tool as name", description: "If enabled, the tool will be called with the tool description rather than the tool number.", group : "preferences", type : "boolean", value : false, scope : "post" }, precisionLevel: { title : "Dynamics profile", description: "Activation of the dynamics profile: General, Fast or Precise", group : "preferences", type : "enum", values : [ {title:"General", id:"general"}, {title:"Fast", id:"fast"}, {title:"Precise", id:"precise"} ], value: "General", scope: "post" }, safePositionMethod: { title : "Safe Retracts", description: "Select your desired retract option. 'Clearance Height' retracts to the operation clearance height.", group : "homePositions", type : "enum", values : [ {title:"Clearance Height", id:"clearanceHeight"}, {title:"SP", id:"SP"} ], value: "SP", 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]} // {id: COOLANT_THROUGH_TOOL, on: "M88 P3 (myComment)", off: "M89"} var coolants = [ {id: COOLANT_FLOOD, on: ["VacAutoOff // Automatic graphite vacuum cleaner off", "EmuOn -out // Emulsion on", "HazeVacOn // Option: Mist suctioning on" ], off: [ "EmuOff // Emulsion off", "HazeVacOff // Option: Mist suctioning off" ]}, {id: COOLANT_MIST, on: ["VacAutoOff // Automatic graphite vacuum cleaner off", "M8 // Spray cooling on", "HazeVacOn // Option: Mist suctioning on" ], off: [ "M9 // Spray cooling off", "HazeVacOff // Option: Mist suctioning off" ]}, {id: COOLANT_THROUGH_TOOL, on: ["VacAutoOff // Automatic graphite vacuum cleaner off", "EmuOn -in // Emulsion on", "HazeVacOn // Option: Mist suctioning on" ], off: [ "EmuOff // Emulsion off", "HazeVacOff // Option: Mist suctioning off" ]}, {id:COOLANT_AIR}, {id:COOLANT_AIR_THROUGH_TOOL}, {id:COOLANT_SUCTION}, {id:COOLANT_FLOOD_MIST}, {id:COOLANT_FLOOD_THROUGH_TOOL}, {id:COOLANT_OFF, off:"// no cooling selected"} ]; // fixed settings var closestABC = false; // choose closest machine angles var useCycl205 = false; // use CYCL 205 for universal pecking var maximumLineLength = 80; // the maximum number of charaters allowed in a line var minimumCyclePoints = 5; // minimum number of points in cycle operation to consider for subprogram var permittedCommentChars = " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,=_-/|"; var sequenceNumberIncrement = 1; // increment for sequence numbers var homeAllAxesAtSectionEnd = true; // force retracts and rotary axes reset between toolpathes var lineUp = false; // the alignment angle is calculated based on the specified rotary axis position and the rotation of the coordinate system var SUB_UNKNOWN = 0; var SUB_PATTERN = 1; var SUB_CYCLE = 2; // collected state var sequenceNumber = 1; var activeMovements; // do not use by default var currentWorkOffset; var nextLabel = 1; var optionalSection = false; var subprograms = []; var currentPattern = -1; var firstPattern = false; var currentSubprogram; var definedPatterns = new Array(); var incrementalMode = false; var saveShowSequenceNumbers; var cycleSubprogramIsActive = false; var patternIsActive = false; var incrementalSubprogram; var retracted = false; // specifies that the tool has been retracted to the safe plane var logFileName; var subprogramExtension = "rod"; var tlmType; var retractSSA = false; var radiusCompensationTable = new Table( [" G40", " G41", " G42"], {initial:RADIUS_COMPENSATION_OFF}, "Invalid radius compensation" ); var xyzFormat = createFormat({decimals:(unit == MM ? 3 : 4)}); var abcFormat = createFormat({decimals:3, forceSign:false, scale:DEG}); var feedFormat = createFormat({decimals:(unit == MM ? 0 : 2)}); var txyzFormat = createFormat({decimals:(unit == MM ? 7 : 8), forceSign:true}); var rpmFormat = createFormat({decimals:0}); var secFormat = createFormat({decimals:3}); var paFormat = createFormat({decimals:3, forceSign:true, scale:DEG}); var angleFormat = createFormat({decimals:0, scale:DEG}); var pitchFormat = createFormat({decimals:(unit == MM ? 3 : 4), forceSign:true}); var ratioFormat = createFormat({decimals:3}); var mFormat = createFormat({prefix:" M", decimals:0}); var toolFormat = createFormat({decimals:0}); var gFormat = createFormat({prefix:"G", width:2, zeropad:true, decimals:1}); // presentation formats var spatialFormat = createFormat({decimals:(unit == MM ? 3 : 4)}); var taperFormat = angleFormat; // share format var xOutput = createVariable({prefix:" X"}, xyzFormat); var yOutput = createVariable({prefix:" Y"}, xyzFormat); var zOutput = createVariable({onchange:function () {retracted = false;}, prefix:" Z"}, xyzFormat); var txOutput = createVariable({prefix:" TX", force:true}, txyzFormat); var tyOutput = createVariable({prefix:" TY", force:true}, txyzFormat); var tzOutput = createVariable({prefix:" TZ", force:true}, txyzFormat); var aOutput = createVariable({prefix:" A"}, abcFormat); var bOutput = createVariable({prefix:" B"}, abcFormat); var cOutput = createVariable({prefix:" C"}, abcFormat); var feedOutput = createVariable({prefix:" F"}, feedFormat); var sOutput = createVariable({prefix:"S", force:true}, rpmFormat); var gMotionModal = createModal({force:true}, gFormat); // modal group 1 // G0-G3, ... var gAbsIncModal = createModal({}, gFormat); // modal group 3 // G90-91 // 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); /** 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(); } /** Writes the specified block. */ function writeBlock() { var text = formatWords(arguments); if (!text) { return; } if (getProperty("showSequenceNumbers") == "true") { if (optionalSection) { if (text) { writeWords("// ", "N" + sequenceNumber, text); } } else { writeWords2("N" + sequenceNumber, arguments); } sequenceNumber += sequenceNumberIncrement; } else { if (optionalSection) { writeWords2("// ", arguments); } else { writeWords(arguments); } } } /** Writes the specified block as optional. */ function writeOptionalBlock() { if (getProperty("showSequenceNumbers") == "true") { var words = formatWords(arguments); if (words) { writeWords("// ", "N" + sequenceNumber, words); sequenceNumber += sequenceNumberIncrement; } } else { writeWords2("// ", arguments); } } function formatComment(text) { return "// " + filterText(String(text).toUpperCase(), permittedCommentChars).replace(/[()]/g, ""); } /** Writes the specified block - used for tool changes only. */ function writeToolBlock() { var show = getProperty("showSequenceNumbers"); setProperty("showSequenceNumbers", (show == "true" || show == "toolChange") ? "true" : "false"); writeBlock(arguments); setProperty("showSequenceNumbers", show); } /** Output a comment. */ function writeComment(text) { writeln(formatComment(text)); } /** Writes a separator. */ function writeSeparator() { writeComment("-------------------------------------"); } function onOpen() { if (false) { // NOTE: setup your machine here var aAxis = createAxis({coordinate:0, table:true, axis:[1, 0, 0], range:[-120.0001, 120.0001], preference:-1}); //var bAxis = createAxis({coordinate:1, table:true, axis:[0, 1, 0], range:[-120.0001, 120.0001], preference:1}); var cAxis = createAxis({coordinate:2, table:true, axis:[0, 0, 1]}); machineConfiguration = new MachineConfiguration(aAxis, cAxis); setMachineConfiguration(machineConfiguration); optimizeMachineAngles2(0); // using TCP mode } if (!machineConfiguration.isMachineCoordinate(0)) { aOutput.disable(); } if (!machineConfiguration.isMachineCoordinate(1)) { bOutput.disable(); } if (!machineConfiguration.isMachineCoordinate(2)) { cOutput.disable(); } if (machineConfiguration.isMultiAxisConfiguration()) { setTCP(false); } if (getProperty("useFilesForSubprograms")) { setProperty("useSubroutines", "allOperations"); // automatically enable subroutines if 'useFilesForSubprograms' is selected } var verticalStockToLeave = getSection(0).hasParameter("operation:verticalStockToLeave") ? xyzFormat.getResultingValue(getSection(0).getParameter("operation:verticalStockToLeave")) : 0; // radial stock to leave // axial stock to leave var feedDeclaration = []; var numberOfSections = getNumberOfSections(); for (i = 0; i < numberOfSections; ++i) { var section = getSection(i); if (section.hasParameter("operation:verticalStockToLeave")) { if (verticalStockToLeave > xyzFormat.getResultingValue(section.getParameter("operation:verticalStockToLeave"))) { verticalStockToLeave = xyzFormat.getResultingValue(section.getParameter("operation:verticalStockToLeave")); } } if (getProperty("useParametricFeed")) { var activeFeeds = initializeActiveFeeds(section); for (var j = 0; j < activeFeeds.length; ++j) { var feedVariable = "VAR $F" + (10 + activeFeeds[j].id) + " // " + activeFeeds[j].description; if (feedDeclaration.indexOf(feedVariable) == -1) { feedDeclaration.push(feedVariable); } } } } writeProgramHeader(); if (getProperty("preloadTool")) { if (!getProperty("toolAsName")) { error(" " + localize("Tool look ahead is only possible with property" + "\"" + " toolAsName: true" + "\"")); return; } var tools = getToolTable(); if (tools.getNumberOfTools() > 0) { for (var i = 0; i < tools.getNumberOfTools(); ++i) { var tool = tools.getTool(i); writeBlock("TT_La=" + "\"" + tool.description + "\""); } } writeln(""); } // declaration of all feed types if (getProperty("useParametricFeed") && feedDeclaration.length > 0) { writeComment("--- Used Feedtypes ---"); writeBlock(feedDeclaration.join("\n")); } if (getProperty("measureTools") == "startEnd") { writeln(""); writeBlock("VAR $TlmType // Tool check: 0=no; 1=only length; 2=length and diameter; 3=fast"); } if (lineUp) { writeBlock("VAR $LineUp = 0 // LineUp : 1 = Activate the automatic alignment of the rotary axes (RotZero); 0 = Offset of the active coordinate system"); } writeBlock("Set_Offset_R -od -tor // change calculation rule for 2D radius correction"); writeln(""); writeBlock("PROTOCOL -start -head"); writeBlock("MDC -Start -User1=" + "\"" + "Hauptprogramm" + "\""); writeln(""); writeComment(" --- Begin machining ---"); setWCS(); writeComment(" --- Dynamic ---"); writeBlock("Cam_Undersize=" + verticalStockToLeave + " // Workpiece undersize (minimum oversize of all programs)"); // set tolerance mode writeBlock("DynAuto=" + "\"" + getProperty("precisionLevel") + "\"" + " // ADPA rule" + "\"" + getProperty("precisionLevel") + "\""); writeln(""); writeComment(" --- Options ---"); writeComment("Set_Warmup=120 // manual user spindle warmup"); writeComment("Set_Offset_R=0.00 // manual user offset for 2D_compensation"); writeln(""); if (getProperty("writeTools")) { writeToolTable(); } } function onComment(message) { writeComment(message); } function invalidateXYZ() { xOutput.reset(); yOutput.reset(); zOutput.reset(); } function forceFeed() { currentFeedId = undefined; feedOutput.reset(); } /** Invalidates the current position and feedrate. Invoke this function to force X, Y, Z, A, B, C, and F in the following block. */ function invalidate() { xOutput.reset(); yOutput.reset(); zOutput.reset(); aOutput.reset(); bOutput.reset(); cOutput.reset(); forceFeed(); } var currentWorkPlaneABC = undefined; 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 if (_section.isMultiAxis()) { forceWorkPlane(); cancelTransformation(); abc = _section.getInitialToolAxisABC(); } else { abc = getWorkPlaneMachineABC(_section.workPlane, _setWorkPlane); if (_setWorkPlane) { setWorkPlane(abc, true); } } } 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, turn) { 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 } if (!retracted) { writeRetract(Z); } gMotionModal.reset(); forceABC(); writeln(""); if (turn) { if (abc.isNonZero()) { writeComment("start_3plus_2axis"); } else { writeComment("start_3axis"); } writeComment("Positioning of the rotary axes, carrying along the zero point"); } if (lineUp && turn) { writeBlock("If ($LineUp == 1)"); writeRotZero(abc, " -LineUp // Zero point offset for rotary axis machines (no traversing movement)"); writeBlock("LineUp"); writeBlock("Else"); } writeRotZero(abc, " // Zero point offset for rotary axis machines (no traversing movement)"); if (machineConfiguration.isMachineCoordinate(2)) { writeBlock(gMotionModal.format(1), "C" + abcFormat.format(abc.z) + feedOutput.format(highFeedrate)); } if (machineConfiguration.isMachineCoordinate(0)) { writeBlock(gMotionModal.format(1), "A" + abcFormat.format(abc.x) + feedOutput.format(highFeedrate)); } if (machineConfiguration.isMachineCoordinate(1)) { writeBlock(gMotionModal.format(1), "B" + abcFormat.format(abc.y) + feedOutput.format(highFeedrate)); } if (lineUp && turn) { writeBlock("EndIf"); } currentWorkPlaneABC = abc; forceABC(); } 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; // keep false for CYCL 19 if (tcp) { setRotation(W); // TCP mode } else { var O = machineConfiguration.getOrientation(abc); var R = machineConfiguration.getRemainingOrientation(abc, W); setRotation(R); } return abc; } function FeedContext(id, description, feed) { this.id = id; this.description = description; this.feed = feed; } /** Maps the specified feed value to Q feed or formatted 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" + (10 + feedContext.id); } } currentFeedId = undefined; // force Q feed next time } return feedOutput.format(f); // use feed value } function initializeActiveFeeds(section) { activeMovements = new Array(); var movements = section.getMovements(); var id = 0; var activeFeeds = new Array(); if (section.hasParameter("operation:tool_feedCutting")) { if (movements & ((1 << MOVEMENT_CUTTING) | (1 << MOVEMENT_LINK_TRANSITION) | (1 << MOVEMENT_EXTENDED))) { var feedContext = new FeedContext(id, localize("Cutting"), section.getParameter("operation:tool_feedCutting")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_CUTTING] = feedContext; if (!section.hasParameter("operation:tool_feedTransition")) { activeMovements[MOVEMENT_LINK_TRANSITION] = feedContext; } activeMovements[MOVEMENT_EXTENDED] = feedContext; } ++id; if (movements & (1 << MOVEMENT_PREDRILL)) { feedContext = new FeedContext(id, localize("Predrilling"), section.getParameter("operation:tool_feedCutting")); activeMovements[MOVEMENT_PREDRILL] = feedContext; activeFeeds.push(feedContext); } ++id; } if (section.hasParameter("operation:finishFeedrate")) { if (movements & (1 << MOVEMENT_FINISH_CUTTING)) { var feedContext = new FeedContext(id, localize("Finish"), section.getParameter("operation:finishFeedrate")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_FINISH_CUTTING] = feedContext; } ++id; } else if (section.hasParameter("operation:tool_feedCutting")) { if (movements & (1 << MOVEMENT_FINISH_CUTTING)) { var feedContext = new FeedContext(id, localize("Finish"), section.getParameter("operation:tool_feedCutting")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_FINISH_CUTTING] = feedContext; } ++id; } if (section.hasParameter("operation:tool_feedEntry")) { if (movements & (1 << MOVEMENT_LEAD_IN)) { var feedContext = new FeedContext(id, localize("Entry"), section.getParameter("operation:tool_feedEntry")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_LEAD_IN] = feedContext; } ++id; } if (section.hasParameter("operation:tool_feedExit")) { if (movements & (1 << MOVEMENT_LEAD_OUT)) { var feedContext = new FeedContext(id, localize("Exit"), section.getParameter("operation:tool_feedExit")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_LEAD_OUT] = feedContext; } ++id; } if (section.hasParameter("operation:noEngagementFeedrate")) { if (movements & (1 << MOVEMENT_LINK_DIRECT)) { var feedContext = new FeedContext(id, localize("Direct"), section.getParameter("operation:noEngagementFeedrate")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_LINK_DIRECT] = feedContext; } ++id; } else if (section.hasParameter("operation:tool_feedCutting") && section.hasParameter("operation:tool_feedEntry") && section.hasParameter("operation:tool_feedExit")) { if (movements & (1 << MOVEMENT_LINK_DIRECT)) { var feedContext = new FeedContext(id, localize("Direct"), Math.max(section.getParameter("operation:tool_feedCutting"), section.getParameter("operation:tool_feedEntry"), section.getParameter("operation:tool_feedExit"))); activeFeeds.push(feedContext); activeMovements[MOVEMENT_LINK_DIRECT] = feedContext; } ++id; } if (section.hasParameter("operation:reducedFeedrate")) { if (movements & (1 << MOVEMENT_REDUCED)) { var feedContext = new FeedContext(id, localize("Reduced"), section.getParameter("operation:reducedFeedrate")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_REDUCED] = feedContext; } ++id; } if (section.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"), section.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 (section.hasParameter("operation:tool_feedPlunge")) { if (movements & (1 << MOVEMENT_PLUNGE)) { var feedContext = new FeedContext(id, localize("Plunge"), section.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 (section.hasParameter("operation:highFeedrateMode") && section.getParameter("operation:highFeedrateMode") != "disabled") { feed = section.getParameter("operation:highFeedrate"); } else { feed = this.highFeedrate; } var feedContext = new FeedContext(id, localize("High Feed"), feed); activeFeeds.push(feedContext); activeMovements[MOVEMENT_HIGH_FEED] = feedContext; activeMovements[MOVEMENT_RAPID] = feedContext; } ++id; } if (section.hasParameter("operation:tool_feedTransition")) { if (movements & (1 << MOVEMENT_LINK_TRANSITION)) { var feedContext = new FeedContext(id, localize("Transition"), section.getParameter("operation:tool_feedTransition")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_LINK_TRANSITION] = feedContext; } ++id; } if (initializeActiveFeeds.caller.name == "onOpen") { return activeFeeds; } else { for (var i = 0; i < activeFeeds.length; ++i) { var feedContext = activeFeeds[i]; writeBlock("$F" + (10 + feedContext.id) + "=" + feedFormat.format(feedContext.feed) + " ; " + feedContext.description); } return undefined; } } /** 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 = nextLabel++; } definedPatterns.push({ patternType : SUB_PATTERN, patternId : currentPattern, subProgram : currentSubprogram, validPattern : usePattern, initialPosition: _initialPosition, finalPosition : _initialPosition }); } if (usePattern) { if (!_retracted && !_zIsOutput) { writeBlock("L" + zOutput.format(_initialPosition.z) + " FMAX"); } // call subprogram subprogramCall(); 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 = nextLabel++; } 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 = nextLabel++; subprogramCall(); firstPattern = true; subprogramStart(_initialPosition, _abc, false); } } function subprogramStart(_initialPosition, _abc, _incremental) { if (getProperty("useFilesForSubprograms")) { // used if external files are used for subprograms var subprogram = "sub" + currentSubprogram; // set the subprogram name var path = FileSystem.getCombinedPath(FileSystem.getFolderPath(getOutputPath()), subprogram + "." + subprogramExtension); // set the output path for the subprogram(s) redirectToFile(path); // redirect output to the new file (defined above) } else { redirectToBuffer(); var comment = ""; if (hasParameter("operation-comment")) { comment = getParameter("operation-comment"); } writeln( "LBL " + currentSubprogram + conditional(comment, formatComment(comment.substr(0, maximumLineLength - 2 - 6 - 1))) ); saveShowSequenceNumbers = getProperty("showSequenceNumbers"); setProperty("showSequenceNumbers", "false"); if (_incremental) { setIncrementalMode(_initialPosition, _abc); } } } function subprogramCall() { if (getProperty("useFilesForSubprograms")) { writeBlock("XCALL " + "sub" + currentSubprogram + "." + subprogramExtension); // call subprogram } else { writeBlock("CALL LBL" + currentSubprogram); } } function subprogramEnd() { if (firstPattern) { if (!getProperty("useFilesForSubprograms")) { writeBlock("LBL 0"); // sets the end block of the subroutine writeln(""); subprograms += getRedirectionBuffer(); } else { if (currentSection.isMultiAxis()) { setTCP(false); writeRetract(Z); } else { setWorkPlane(new Vector(0, 0, 0), false); } invalidate(); writeBlock(mFormat.format(30)); } } invalidate(); 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 writeToolCall() { if (getProperty("toolAsName")) { writeToolBlock("TT=" + "\"" + (tool.description.toUpperCase()) + "\"" + "-d=" + spatialFormat.format(tool.diameter) + " -re=" + spatialFormat.format(tool.cornerRadius)); } else { writeToolBlock("T" + toolFormat.format(tool.number)); } writeBlock(sOutput.format(spindleSpeed) + mFormat.format(tool.clockwise ? 3 : 4)); writeBlock("WarmUp // Warm-up (according to default or TT)"); writeln(""); } function writeProgramHeader() { writeComment(" --- Info ---"); if (programComment) { writeComment(programComment); } 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)) { writeSeparator(); writeComment(localize("Machine")); if (vendor) { writeComment(" " + localize("vendor") + ": " + vendor); } if (model) { writeComment(" " + localize("model") + ": " + model); } if (description) { writeComment(" " + localize("description") + ": " + description); } writeSeparator(); writeComment(""); } writeComment(" --- Init ---"); if (machineConfiguration.isMultiAxisConfiguration()) { writeBlock("TCorrOff // Deactivate RTCP function"); writeBlock("RMO // Reset the rotary axis coordinates"); writeln(""); } } function onSection() { if (getProperty("toolAsName") && !tool.description) { if (hasParameter("operation-comment")) { error(subst(localize("Tool description is empty in operation \"%1\"."), getParameter("operation-comment").toUpperCase())); } else { error(localize("Tool description is empty.")); } return; } var forceToolAndRetract = optionalSection && !currentSection.isOptional(); optionalSection = currentSection.isOptional(); var insertToolCall = forceToolAndRetract || isFirstSection() || (currentSection.getForceToolChange && currentSection.getForceToolChange()) || (tool.number != getPreviousSection().getTool().number) || (tool.clockwise != getPreviousSection().getTool().clockwise) || conditional(getProperty("toolAsName"), tool.description != getPreviousSection().getTool().description); retracted = false; // specifies that the tool has been retracted to the safe plane 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 var abc = defineWorkPlane(currentSection, false); var initialPosition = getFramePosition(currentSection.getInitialPosition()); if (hasParameter("operation-comment")) { var comment = getParameter("operation-comment"); } if (currentSection.isPatterned() && (getProperty("useSubroutines") == "patterns") && getProperty("useFilesForSubprograms")) { error(localize("You cannot use property 'use subroutine patterns' together with property 'use files for subroutines'.")); return; } if (getProperty("useFilesForSubprograms")) { if (isFirstSection() && (getProperty("useSubroutines") == "allOperations") && (getProperty("useSubroutines") == "patterns")) { writeRetract(Z); } if (getProperty("writeTools") && insertToolCall) { writeToolDescription(); } writeTlmType(); setWCS(); // start subprogram subprogramDefine(initialPosition, abc, retracted, zIsOutput); writeProgramHeader(); writeToolTable(); writeComment(" --- Begin machining ---"); if (comment) { writeComment(comment); } writeToolCall(); writeMeasureTools(); } else { writeln(""); if (isFirstSection()) { writeComment(" --- Begin machining ---"); } if (comment) { writeComment(comment); } setWCS(); if (insertToolCall) { if (getProperty("writeTools")) { writeToolDescription(); } writeToolCall(); if (getProperty("measureTools") == "startEnd" && isFirstSection()) { writeBlock("$TlmType=1"); } writeMeasureTools(); } } writeDynamics(); retractSSA = isFirstSection() || getProperty("useFilesForSubprograms"); if (getProperty("useFilesForSubprograms") || (homeAllAxesAtSectionEnd || insertToolCall || newWorkOffset || newWorkPlane)) { writeRetract(Z); } if (isFirstSection() || getProperty("useFilesForSubprograms")) { writeBlock("WaitC // Option: Program pause, if it was activated"); } 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(currentSection); } } else { activeMovements = undefined; } writeln(""); setCoolant(tool.coolant); if (currentSection.isMultiAxis()) { writeComment(" Pre-positioning with activation of the rotary axis correction"); writeBlock( "MOVZERO=" + " X=" + xyzFormat.format(initialPosition.x) + ";" + " Y=" + xyzFormat.format(initialPosition.y) + ";" + " Z=" + xyzFormat.format(initialPosition.z) ); writeRotZero(abc, " // Zero point offset for rotary axis machines (no traversing movement)"); writeBlock( gMotionModal.format(1) + conditional(machineConfiguration.isMachineCoordinate(0), aOutput.format(abc.x)) + conditional(machineConfiguration.isMachineCoordinate(1), bOutput.format(abc.y)) + conditional(machineConfiguration.isMachineCoordinate(2), cOutput.format(abc.z)) + feedOutput.format(highFeedrate) ); writeBlock(gMotionModal.format(1) + yOutput.format(0)); writeBlock(gMotionModal.format(1) + xOutput.format(0)); writeBlock(gMotionModal.format(1) + zOutput.format(0)); forceXYZ(); writeRotZero(new Vector(0, 0, 0)); writeBlock( "MOVZERO=" + " X=" + xyzFormat.format(initialPosition.x * -1) + ";" + " Y=" + xyzFormat.format(initialPosition.y * -1) + ";" + " Z=" + xyzFormat.format(initialPosition.z * -1) ); writeln(""); setTCP(true); forceABC(); writeBlock( gMotionModal.format(1) + conditional(machineConfiguration.isMachineCoordinate(0), aOutput.format(abc.x)) + conditional(machineConfiguration.isMachineCoordinate(1), bOutput.format(abc.y)) + conditional(machineConfiguration.isMachineCoordinate(2), cOutput.format(abc.z)) + feedOutput.format(highFeedrate) ); forceXYZ(); } else { // indexing if (!getProperty("useFilesForSubprograms")) { if (homeAllAxesAtSectionEnd || insertToolCall || newWorkOffset || newWorkPlane) { defineWorkPlane(currentSection, true); } } else { defineWorkPlane(currentSection, true); } if (getProperty("useFilesForSubprograms")) { writeln(""); writeBlock("HEADEREND // End of the program header"); writeln(""); } writeBlock(gMotionModal.format(0) + xOutput.format(initialPosition.x) + yOutput.format(initialPosition.y)); z = zOutput.format(initialPosition.z); if (z) { writeBlock(gMotionModal.format(0) + z); } zIsOutput = true; } if (!getProperty("useFilesForSubprograms")) { subprogramDefine(initialPosition, abc, retracted, zIsOutput); } retracted = false; } function setTCP(tcp) { if (typeof currentSection == "undefined" || (currentSection.isOptimizedForMachine() && currentSection.getOptimizedTCPMode() != 0)) { return; } if (tcp) { writeBlock("TCorrOn -rt // Activate RTCP function (tool tip)"); } else { writeBlock("TCorrOff // Deactivate RTCP function"); writeBlock("RMO // Reset the rotary axis coordinates"); } } function setWCS() { var workOffset; if (typeof currentSection == "undefined") { workOffset = getSection(0).workOffset; } else { workOffset = currentSection.workOffset; } if (workOffset != currentWorkOffset) { writeBlock("MaCoor -all // Reset all coordinate shifts"); writeBlock("LoadZero=" + "\"" + workOffset + "\"" + "-h=0.0 // Example: Workpiece zero point from zero point memory"); writeln(""); currentWorkOffset = workOffset; } } function getNextToolDescription(description) { var currentSectionId = getCurrentSectionId(); if (currentSectionId < 0) { return null; } for (var i = currentSectionId + 1; i < getNumberOfSections(); ++i) { var section = getSection(i); var sectionTool = section.getTool(); if (description != sectionTool.description) { return sectionTool; // found next tool } } return null; // not found } function onDwell(seconds) { validate(seconds >= 0); writeBlock("CYCL DEF 9.0 " + localize("DWELL TIME")); writeBlock("CYCL DEF 9.1 DWELL " + secFormat.format(seconds)); } var probeOutputWorkOffset = 1; function onParameter(name, value) { if (name == "operation-structure-comment") { writeStructureComment(" " + value); } if (name == "probe-output-work-offset") { probeOutputWorkOffset = value; } } function onSpindleSpeed(spindleSpeed) { writeBlock(sOutput.format(spindleSpeed)); } function onDrilling(cycle) { writeBlock("CYCL DEF 200 " + localize("DRILLING") + " ~" + EOL + " Q200=" + xyzFormat.format(cycle.retract - cycle.stock) + " ;" + localize("SET-UP CLEARANCE") + " ~" + EOL + " Q201=" + xyzFormat.format(-cycle.depth) + " ;" + localize("DEPTH") + " ~" + EOL + " Q206=" + feedFormat.format(cycle.feedrate) + " ;" + localize("FEED RATE FOR PLUNGING") + " ~" + EOL + " Q202=" + xyzFormat.format(cycle.depth) + " ;" + localize("INFEED DEPTH") + " ~" + EOL + " Q210=" + secFormat.format(0) + " ;" + localize("DWELL AT TOP") + " ~" + EOL + " Q203=" + xyzFormat.format(cycle.stock) + " ;" + localize("SURFACE COORDINATE") + " ~" + EOL + " Q204=" + xyzFormat.format(cycle.clearance - cycle.stock) + " ;" + localize("2ND SET-UP CLEARANCE") + " ~" + EOL + " Q211=" + secFormat.format(0) + " ;" + localize("DWELL AT BOTTOM") ); } function onCounterBoring(cycle) { writeBlock("CYCL DEF 200 " + localize("DRILLING") + " ~" + EOL + " Q200=" + xyzFormat.format(cycle.retract - cycle.stock) + " ;" + localize("SET-UP CLEARANCE") + " ~" + EOL + " Q201=" + xyzFormat.format(-cycle.depth) + " ;" + localize("DEPTH") + " ~" + EOL + " Q206=" + feedFormat.format(cycle.feedrate) + " ;" + localize("FEED RATE FOR PLUNGING") + " ~" + EOL + " Q202=" + xyzFormat.format(cycle.depth) + " ;" + localize("INFEED DEPTH") + " ~" + EOL + " Q210=" + secFormat.format(0) + " ;" + localize("DWELL AT TOP") + " ~" + EOL + " Q203=" + xyzFormat.format(cycle.stock) + " ;" + localize("SURFACE COORDINATE") + " ~" + EOL + " Q204=" + xyzFormat.format(cycle.clearance - cycle.stock) + " ;" + localize("2ND SET-UP CLEARANCE") + " ~" + EOL + " Q211=" + secFormat.format(cycle.dwell) + " ;" + localize("DWELL AT BOTTOM") ); } function onChipBreaking(cycle) { writeBlock("CYCL DEF 203 " + localize("UNIVERSAL DRILLING") + " ~" + EOL + " Q200=" + xyzFormat.format(cycle.retract - cycle.stock) + " ;" + localize("SET-UP CLEARANCE") + " ~" + EOL + " Q201=" + xyzFormat.format(-cycle.depth) + " ;" + localize("DEPTH") + " ~" + EOL + " Q206=" + feedFormat.format(cycle.feedrate) + " ;" + localize("FEED RATE FOR PLUNGING") + " ~" + EOL + " Q202=" + xyzFormat.format(cycle.incrementalDepth) + " ;" + localize("INFEED DEPTH") + " ~" + EOL + " Q210=" + secFormat.format(0) + " ;" + localize("DWELL AT TOP") + " ~" + EOL + " Q203=" + xyzFormat.format(cycle.stock) + " ;" + localize("SURFACE COORDINATE") + " ~" + EOL + " Q204=" + xyzFormat.format(cycle.clearance - cycle.stock) + " ;" + localize("2ND SET-UP CLEARANCE") + " ~" + EOL + " Q212=" + xyzFormat.format(cycle.incrementalDepthReduction) + " ;" + localize("DECREMENT") + " ~" + EOL + " Q213=" + cycle.plungesPerRetract + " ;" + localize("BREAKS") + " ~" + EOL + " Q205=" + xyzFormat.format(cycle.minimumIncrementalDepth) + " ;" + localize("MIN. PLUNGING DEPTH") + " ~" + EOL + " Q211=" + secFormat.format(cycle.dwell) + " ;" + localize("DWELL TIME AT DEPTH") + " ~" + EOL + " Q208=" + "MAX" + " ;" + localize("RETRACTION FEED RATE") + " ~" + EOL + " Q256=" + xyzFormat.format((cycle.chipBreakDistance != undefined) ? cycle.chipBreakDistance : machineParameters.chipBreakingDistance) + " ;" + localize("DIST. FOR CHIP BRKNG") ); } function onDeepDrilling(cycle) { if (useCycl205) { writeBlock("CYCL DEF 205 " + localize("UNIVERSAL PECKING") + " ~" + EOL + " Q200=" + xyzFormat.format(cycle.retract - cycle.stock) + " ;" + localize("SET-UP CLEARANCE") + " ~" + EOL + " Q201=" + xyzFormat.format(-cycle.depth) + " ;" + localize("DEPTH") + " ~" + EOL + " Q206=" + feedFormat.format(cycle.feedrate) + " ;" + localize("FEED RATE FOR PLUNGING") + " ~" + EOL + " Q202=" + xyzFormat.format(cycle.incrementalDepth) + " ;" + localize("PLUNGING DEPTH") + " ~" + EOL + " Q203=" + xyzFormat.format(cycle.stock) + " ;" + localize("SURFACE COORDINATE") + " ~" + EOL + " Q204=" + xyzFormat.format(cycle.clearance - cycle.stock) + " ;" + localize("2ND SET-UP CLEARANCE") + " ~" + EOL + " Q212=" + xyzFormat.format(cycle.incrementalDepthReduction) + " ;" + localize("DECREMENT") + " ~" + EOL + " Q205=" + xyzFormat.format(cycle.minimumIncrementalDepth) + " ;" + localize("MIN. PLUNGING DEPTH") + " ~" + EOL + " Q258=" + xyzFormat.format(0.5) + " ;" + localize("UPPER ADV. STOP DIST.") + " ~" + EOL + " Q259=" + xyzFormat.format(1) + " ;" + localize("LOWER ADV. STOP DIST.") + " ~" + EOL + " Q257=" + xyzFormat.format(5) + " ;" + localize("DEPTH FOR CHIP BRKNG") + " ~" + EOL + " Q256=" + xyzFormat.format((cycle.chipBreakDistance != undefined) ? cycle.chipBreakDistance : machineParameters.chipBreakingDistance) + " ;" + localize("DIST. FOR CHIP BRKNG") + " ~" + EOL + " Q211=" + secFormat.format(cycle.dwell) + " ;" + localize("DWELL TIME AT DEPTH") + " ~" + EOL + " Q379=" + "0" + " ;" + localize("STARTING POINT") + " ~" + EOL + " Q253=" + feedFormat.format(cycle.retractFeedrate) + " ;" + localize("F PRE-POSITIONING") ); } else { writeBlock("CYCL DEF 200 " + localize("DRILLING") + " ~" + EOL + " Q200=" + xyzFormat.format(cycle.retract - cycle.stock) + " ;" + localize("SET-UP CLEARANCE") + " ~" + EOL + " Q201=" + xyzFormat.format(-cycle.depth) + " ;" + localize("DEPTH") + " ~" + EOL + " Q206=" + feedFormat.format(cycle.feedrate) + " ;" + localize("FEED RATE FOR PLUNGING") + " ~" + EOL + " Q202=" + xyzFormat.format(cycle.incrementalDepth) + " ;" + localize("INFEED DEPTH") + " ~" + EOL + " Q210=" + secFormat.format(0) + " ;" + localize("DWELL AT TOP") + " ~" + EOL + " Q203=" + xyzFormat.format(cycle.stock) + " ;" + localize("SURFACE COORDINATE") + " ~" + EOL + " Q204=" + xyzFormat.format(cycle.clearance - cycle.stock) + " ;" + localize("2ND SET-UP CLEARANCE") + " ~" + EOL + " Q211=" + secFormat.format(cycle.dwell) + " ;" + localize("DWELL AT BOTTOM") ); } } function onGunDrilling(cycle) { var coolantCode = getCoolantCode(tool.coolant); writeBlock("CYCL DEF 241 " + localize("SINGLE-FLUTED DEEP-HOLE DRILLING") + " ~" + EOL + " Q200=" + xyzFormat.format(cycle.retract - cycle.stock) + " ;" + localize("SET-UP CLEARANCE") + " ~" + EOL + " Q201=" + xyzFormat.format(-cycle.depth) + " ;" + localize("DEPTH") + " ~" + EOL + " Q206=" + feedFormat.format(cycle.feedrate) + " ;" + localize("FEED RATE FOR PLUNGING") + " ~" + EOL + " Q211=" + secFormat.format(cycle.dwell) + " ;" + localize("DWELL TIME AT DEPTH") + " ~" + EOL + " Q203=" + xyzFormat.format(cycle.stock) + " ;" + localize("SURFACE COORDINATE") + " ~" + EOL + " Q204=" + xyzFormat.format(cycle.clearance - cycle.stock) + " ;" + localize("2ND SET-UP CLEARANCE") + " ~" + EOL + " Q379=" + xyzFormat.format(cycle.startingDepth) + " ;" + localize("STARTING POINT") + " ~" + EOL + " Q253=" + feedFormat.format(cycle.positioningFeedrate) + " ;" + localize("F PRE-POSITIONING") + " ~" + EOL + " Q208=" + feedFormat.format(cycle.retractFeedrate) + " ;" + localize("RETRACT FEED RATE") + " ~" + EOL + " Q426=" + (cycle.stopSpindle ? 5 : (tool.clockwise ? 3 : 4)) + " ;" + localize("DIR. OF SPINDLE ROT.") + " ~" + EOL + " Q427=" + rpmFormat.format(cycle.positioningSpindleSpeed ? cycle.positioningSpindleSpeed : tool.spindleRPM) + " ;" + localize("ENTRY EXIT SPEED") + " ~" + EOL + " Q428=" + rpmFormat.format(tool.spindleRPM) + " ;" + localize("DRILLING SPEED") + " ~" + EOL + conditional(coolantCode, " Q429=" + (coolantCode ? coolantCode[0] : 0) + " ;" + localize("COOLANT ON") + " ~" + EOL) + conditional(coolantCode, " Q430=" + (coolantCode ? coolantCode[1] : 0) + " ;" + localize("COOLANT OFF") + " ~" + EOL) // Heidenhain manual doesn't specify Q435 fully - adjust to fit CNC + " Q435=" + xyzFormat.format(cycle.dwellDepth ? (cycle.depth + cycle.dwellDepth) : 0) + " ;" + localize("DWELL DEPTH") // 0 to disable ); } function onTapping(cycle) { writeBlock("CYCL DEF 207 " + localize("RIGID TAPPING NEW") + " ~" + EOL + " Q200=" + xyzFormat.format(cycle.retract - cycle.stock) + " ;" + localize("SET-UP CLEARANCE") + " ~" + EOL + " Q201=" + xyzFormat.format(-cycle.depth) + " ;" + localize("DEPTH") + " ~" + EOL + " Q239=" + pitchFormat.format((tool.type == TOOL_TAP_LEFT_HAND ? -1 : 1) * tool.threadPitch) + " ;" + localize("THREAD PITCH") + " ~" + EOL + " Q203=" + xyzFormat.format(cycle.stock) + " ;" + localize("SURFACE COORDINATE") + " ~" + EOL + " Q204=" + xyzFormat.format(cycle.clearance - cycle.stock) + " ;" + localize("2ND SET-UP CLEARANCE") ); } function onTappingWithChipBreaking(cycle) { writeBlock("CYCL DEF 209 " + localize("TAPPING W/ CHIP BRKG") + " ~" + EOL + " Q200=" + xyzFormat.format(cycle.retract - cycle.stock) + " ;" + localize("SET-UP CLEARANCE") + " ~" + EOL + " Q201=" + xyzFormat.format(-cycle.depth) + " ;" + localize("DEPTH") + " ~" + EOL + " Q239=" + pitchFormat.format((tool.type == TOOL_TAP_LEFT_HAND ? -1 : 1) * tool.threadPitch) + " ;" + localize("THREAD PITCH") + " ~" + EOL + " Q203=" + xyzFormat.format(cycle.stock) + " ;" + localize("SURFACE COORDINATE") + " ~" + EOL + " Q204=" + xyzFormat.format(cycle.clearance - cycle.stock) + " ;" + localize("2ND SET-UP CLEARANCE") + " ~" + EOL + " Q257=" + xyzFormat.format(cycle.incrementalDepth) + " ;" + localize("DEPTH FOR CHIP BRKNG") + " ~" + EOL + " Q256=" + xyzFormat.format((cycle.chipBreakDistance != undefined) ? cycle.chipBreakDistance : machineParameters.chipBreakingDistance) + " ;" + localize("DIST. FOR CHIP BRKNG") + " ~" + EOL + " Q336=" + angleFormat.format(0) + " ;" + localize("ANGLE OF SPINDLE") ); } function onReaming(cycle) { writeBlock("CYCL DEF 201 " + localize("REAMING") + " ~" + EOL + " Q200=" + xyzFormat.format(cycle.retract - cycle.stock) + " ;" + localize("SET-UP CLEARANCE") + " ~" + EOL + " Q201=" + xyzFormat.format(-cycle.depth) + " ;" + localize("DEPTH") + " ~" + EOL + " Q206=" + feedFormat.format(cycle.feedrate) + " ;" + localize("FEED RATE FOR PLUNGING") + " ~" + EOL + " Q211=" + secFormat.format(cycle.dwell) + " ;" + localize("DWELL AT BOTTOM") + " ~" + EOL + " Q208=" + feedFormat.format(cycle.retractFeedrate) + " ;" + localize("RETRACTION FEED TIME") + " ~" + EOL // retract at reaming feed rate + " Q203=" + xyzFormat.format(cycle.stock) + " ;" + localize("SURFACE COORDINATE") + " ~" + EOL + " Q204=" + xyzFormat.format(cycle.clearance - cycle.stock) + " ;" + localize("2ND SET-UP CLEARANCE") ); } function onStopBoring(cycle) { writeBlock("CYCL DEF 202 " + localize("BORING") + " ~" + EOL + " Q200=" + xyzFormat.format(cycle.retract - cycle.stock) + " ;" + localize("SET-UP CLEARANCE") + " ~" + EOL + " Q201=" + xyzFormat.format(-cycle.depth) + " ;" + localize("DEPTH") + " ~" + EOL + " Q206=" + feedFormat.format(cycle.feedrate) + " ;" + localize("FEED RATE FOR PLUNGING") + " ~" + EOL + " Q211=" + secFormat.format(cycle.dwell) + " ;" + localize("DWELL AT BOTTOM") + " ~" + EOL + " Q208=" + "MAX" + " ;" + localize("RETRACTION FEED RATE") + " ~" + EOL + " Q203=" + xyzFormat.format(cycle.stock) + " ;" + localize("SURFACE COORDINATE") + " ~" + EOL + " Q204=" + xyzFormat.format(cycle.clearance - cycle.stock) + " ;" + localize("2ND SET-UP CLEARANCE") + " ~" + EOL + " Q214=" + 0 + " ;" + localize("DISENGAGING DIRECTION") + " ~" + EOL + " Q336=" + angleFormat.format(0) + " ;" + localize("ANGLE OF SPINDLE") ); } /** Returns the best discrete disengagement direction for the specified direction. */ function getDisengagementDirection(direction) { switch (getQuadrant(direction + 45 * Math.PI / 180)) { case 0: return 3; case 1: return 4; case 2: return 1; case 3: return 2; } error(localize("Invalid disengagement direction.")); return 3; } function onFineBoring(cycle) { // we do not support cycle.shift writeBlock("CYCL DEF 202 " + localize("BORING") + " ~" + EOL + " Q200=" + xyzFormat.format(cycle.retract - cycle.stock) + " ;" + localize("SET-UP CLEARANCE") + " ~" + EOL + " Q201=" + xyzFormat.format(-cycle.depth) + " ;" + localize("DEPTH") + " ~" + EOL + " Q206=" + feedFormat.format(cycle.feedrate) + " ;" + localize("FEED RATE FOR PLUNGING") + " ~" + EOL + " Q211=" + secFormat.format(cycle.dwell) + " ;" + localize("DWELL AT BOTTOM") + " ~" + EOL + " Q208=" + "MAX" + " ;" + localize("RETRACTION FEED TIME") + " ~" + EOL + " Q203=" + xyzFormat.format(cycle.stock) + " ;" + localize("SURFACE COORDINATE") + " ~" + EOL + " Q204=" + xyzFormat.format(cycle.clearance - cycle.stock) + " ;" + localize("2ND SET-UP CLEARANCE") + " ~" + EOL + " Q214=" + getDisengagementDirection(cycle.shiftDirection) + " ;" + localize("DISENGAGING DIRECTION") + " ~" + EOL + " Q336=" + angleFormat.format(cycle.compensatedShiftOrientation) + " ;" + localize("ANGLE OF SPINDLE") ); } function onBackBoring(cycle) { writeBlock("CYCL DEF 204 " + localize("BACK BORING") + " ~" + EOL + " Q200=" + xyzFormat.format(cycle.retract - cycle.stock) + " ;" + localize("SET-UP CLEARANCE") + " ~" + EOL + " Q249=" + xyzFormat.format(cycle.backBoreDistance) + " ;" + localize("DEPTH REDUCTION") + " ~" + EOL + " Q250=" + xyzFormat.format(cycle.depth) + " ;" + localize("MATERIAL THICKNESS") + " ~" + EOL + " Q251=" + xyzFormat.format(cycle.shift) + " ;" + localize("OFF-CENTER DISTANCE") + " ~" + EOL + " Q252=" + xyzFormat.format(0) + " ;" + localize("TOOL EDGE HEIGHT") + " ~" + EOL + " Q253=" + "MAX" + " ;" + localize("F PRE-POSITIONING") + " ~" + EOL + " Q254=" + feedFormat.format(cycle.feedrate) + " ;" + localize("F COUNTERBORING") + " ~" + EOL + " Q255=" + secFormat.format(cycle.dwell) + " ;" + localize("DWELL AT BOTTOM") + " ~" + EOL + " Q203=" + xyzFormat.format(cycle.stock) + " ;" + localize("SURFACE COORDINATE") + " ~" + EOL + " Q204=" + xyzFormat.format(cycle.clearance - cycle.stock) + " ;" + localize("2ND SET-UP CLEARANCE") + " ~" + EOL + " Q214=" + getDisengagementDirection(cycle.shiftDirection) + " ;" + localize("DISENGAGING DIRECTION") + " ~" + EOL + " Q336=" + angleFormat.format(cycle.compensatedShiftOrientation) + " ;" + localize("ANGLE OF SPINDLE") ); } function onBoring(cycle) { writeBlock("CYCL DEF 202 " + localize("BORING") + " ~" + EOL + " Q200=" + xyzFormat.format(cycle.retract - cycle.stock) + " ;" + localize("SET-UP CLEARANCE") + " ~" + EOL + " Q201=" + xyzFormat.format(-cycle.depth) + " ;" + localize("DEPTH") + " ~" + EOL + " Q206=" + feedFormat.format(cycle.feedrate) + " ;" + localize("FEED RATE FOR PLUNGING") + " ~" + EOL + " Q211=" + secFormat.format(cycle.dwell) + " ;" + localize("DWELL AT BOTTOM") + " ~" + EOL + " Q208=" + feedFormat.format(cycle.retractFeedrate) + " ;" + localize("RETRACTION FEED RATE") + " ~" + EOL // retract at feed + " Q203=" + xyzFormat.format(cycle.stock) + " ;" + localize("SURFACE COORDINATE") + " ~" + EOL + " Q204=" + xyzFormat.format(cycle.clearance - cycle.stock) + " ;" + localize("2ND SET-UP CLEARANCE") + " ~" + EOL + " Q214=" + 0 + " ;" + localize("DISENGAGING DIRECTION") + " ~" + EOL + " Q336=" + angleFormat.format(0) + " ;" + localize("ANGLE OF SPINDLE") ); } function onBoreMilling(cycle) { writeBlock("CYCL DEF 208 " + localize("BORE MILLING") + " ~" + EOL + " Q200=" + xyzFormat.format(cycle.retract - cycle.stock) + " ;" + localize("SET-UP CLEARANCE") + " ~" + EOL + " Q201=" + xyzFormat.format(-cycle.depth) + " ;" + localize("DEPTH") + " ~" + EOL + " Q206=" + feedFormat.format(cycle.feedrate) + " ;" + localize("FEED RATE FOR PLUNGING") + " ~" + EOL + " Q334=" + pitchFormat.format(cycle.pitch) + " ;" + localize("INFEED DEPTH") + " ~" + EOL + " Q203=" + xyzFormat.format(cycle.stock) + " ;" + localize("SURFACE COORDINATE") + " ~" + EOL + " Q204=" + xyzFormat.format(cycle.clearance - cycle.stock) + " ;" + localize("2ND SET-UP CLEARANCE") + " ~" + EOL + " Q335=" + xyzFormat.format(cycle.diameter) + " ;" + localize("NOMINAL DIAMETER") + " ~" + EOL + " Q342=" + xyzFormat.format(tool.diameter) + " ;" + localize("ROUGHING DIAMETER") ); } function onThreadMilling(cycle) { cycle.numberOfThreads = 1; writeBlock("CYCL DEF 262 " + localize("THREAD MILLING") + " ~" + EOL + " Q335=" + xyzFormat.format(cycle.diameter) + " ;" + localize("NOMINAL DIAMETER") + " ~" + EOL // + for right-hand and - for left-hand + " Q239=" + pitchFormat.format(cycle.threading == "right" ? cycle.pitch : -cycle.pitch) + " ;" + localize("PITCH") + " ~" + EOL + " Q201=" + xyzFormat.format(-cycle.depth) + " ;" + localize("THREAD DEPTH") + " ~" + EOL // 0 for threads over entire depth + " Q355=" + xyzFormat.format(cycle.numberOfThreads) + " ;" + localize("THREADS PER STEP") + " ~" + EOL + " Q253=" + feedFormat.format(cycle.feedrate) + " ;" + localize("F PRE-POSITIONING") + " ~" + EOL + " Q351=" + xyzFormat.format(cycle.direction == "climb" ? 1 : -1) + " ;" + localize("CLIMB OR UP-CUT") + " ~" + EOL + " Q200=" + xyzFormat.format(cycle.retract - cycle.stock) + " ;" + localize("SET-UP CLEARANCE") + " ~" + EOL + " Q203=" + xyzFormat.format(cycle.stock) + " ;" + localize("SURFACE COORDINATE") + " ~" + EOL + " Q204=" + xyzFormat.format(cycle.clearance - cycle.stock) + " ;" + localize("2ND SET-UP CLEARANCE") + " ~" + EOL + " Q207=" + feedFormat.format(cycle.feedrate) + " ;" + localize("FEED RATE FOR MILLING") ); } function onCircularPocketMilling(cycle) { if (tool.taperAngle > 0) { error(localize("Circular pocket milling is not supported for taper tools.")); return; } // do NOT use with undercutting - doesnt move to the center before retracting writeBlock("CYCL DEF 252 " + localize("CIRCULAR POCKET") + " ~" + EOL + " Q215=1 ;" + localize("MACHINE OPERATION") + " ~" + EOL + " Q223=" + xyzFormat.format(cycle.diameter) + " ;" + localize("CIRCLE DIAMETER") + " ~" + EOL + " Q368=" + xyzFormat.format(0) + " ;" + localize("FINISHING ALLOWANCE FOR SIDE") + " ~" + EOL + " Q207=" + feedFormat.format(cycle.feedrate) + " ;" + localize("FEED RATE FOR MILLING") + " ~" + EOL + " Q351=" + xyzFormat.format(cycle.direction == "climb" ? 1 : -1) + " ;" + localize("CLIMB OR UP-CUT") + " ~" + EOL + " Q201=" + xyzFormat.format(-cycle.depth) + " ;" + localize("DEPTH") + " ~" + EOL + " Q202=" + xyzFormat.format(cycle.incrementalDepth) + " ;" + localize("INFEED DEPTH") + " ~" + EOL + " Q369=" + xyzFormat.format(0) + " ;" + localize("FINISHING ALLOWANCE FOR FLOOR") + " ~" + EOL + " Q206=" + feedFormat.format(cycle.plungeFeedrate) + " ;" + localize("FEED RATE FOR PLUNGING") + " ~" + EOL + " Q338=0 ;" + localize("INFEED FOR FINISHING") + " ~" + EOL + " Q200=" + xyzFormat.format(cycle.retract - cycle.stock) + " ;" + localize("SET-UP CLEARANCE") + " ~" + EOL + " Q203=" + xyzFormat.format(cycle.stock) + " ;" + localize("SURFACE COORDINATE") + " ~" + EOL + " Q204=" + xyzFormat.format(cycle.clearance - cycle.stock) + " ;" + localize("2ND SET-UP CLEARANCE") + " ~" + EOL + " Q370=" + ratioFormat.format(cycle.stepover / (tool.diameter / 2)) + " ;" + localize("TOOL PATH OVERLAP") + " ~" + EOL + " Q366=" + "0" + " ;" + localize("PLUNGING") + " ~" + EOL + " Q385=" + feedFormat.format(cycle.feedrate) + " ;" + localize("FEED RATE FOR FINISHING") ); } function setCyclePosition(_position) { zOutput.format(_position); } var expandCurrentCycle = false; function onCycle() { if (cycleType == "inspect") { return; } if (!isSameDirection(getRotation().forward, new Vector(0, 0, 1))) { expandCurrentCycle = getProperty("expandCycles"); if (!expandCurrentCycle) { cycleNotSupported(); } return; } if (isProbeOperation()) { if (!expandCurrentCycle) { cycleNotSupported(); return; } return; } if (pendingRadiusCompensation >= 0) { error(localize("Radius compensation cannot be activated/deactivated for a circular move.")); return; } expandCurrentCycle = false; if (cycle.clearance != undefined) { if (getCurrentPosition().z < cycle.clearance) { writeBlock("L" + zOutput.format(cycle.clearance) + radiusCompensationTable.lookup(radiusCompensation) + " FMAX"); setCurrentPositionZ(cycle.clearance); } } switch (cycleType) { case "drilling": // G81 style onDrilling(cycle); break; case "counter-boring": onCounterBoring(cycle); break; case "chip-breaking": onChipBreaking(cycle); break; case "deep-drilling": onDeepDrilling(cycle); break; case "gun-drilling": onGunDrilling(cycle); break; case "tapping": case "left-tapping": case "right-tapping": onTapping(cycle); break; case "tapping-with-chip-breaking": case "left-tapping-with-chip-breaking": case "right-tapping-with-chip-breaking": onTappingWithChipBreaking(cycle); break; case "reaming": onReaming(cycle); break; case "stop-boring": onStopBoring(cycle); break; case "fine-boring": onFineBoring(cycle); break; case "back-boring": onBackBoring(cycle); break; case "boring": onBoring(cycle); break; case "bore-milling": if (cycle.numberOfSteps != undefined && cycle.numberOfSteps > 1) { expandCurrentCycle = getProperty("expandCycles"); if (!expandCurrentCycle) { cycleNotSupported(); } } else { onBoreMilling(cycle); } break; case "thread-milling": if (cycle.numberOfSteps != undefined && cycle.numberOfSteps > 1) { expandCurrentCycle = getProperty("expandCycles"); if (!expandCurrentCycle) { cycleNotSupported(); } } else { onThreadMilling(cycle); } break; case "circular-pocket-milling": expandCurrentCycle = true; onCircularPocketMilling(cycle); break; default: expandCurrentCycle = getProperty("expandCycles"); if (!expandCurrentCycle) { cycleNotSupported(); } } } /** Convert approach to sign. */ function approach(value) { validate((value == "positive") || (value == "negative"), "Invalid approach."); return (value == "positive") ? 1 : -1; } function onCyclePoint(x, y, z) { if (cycleType == "inspect") { if (typeof inspectionCycleInspect == "function") { inspectionCycleInspect(cycle, x, y, z); return; } else { cycleNotSupported(); } } if (!expandCurrentCycle) { // execute current cycle after this positioning block /* if (cycleType == "circular-pocket-milling") { if (isFirstCyclePoint()) { onCircularPocketFinishMilling(x, y, cycle); writeBlock("CYCL CALL"); } else { writeBlock("FN 0: Q216 = " + xyzFormat.format(x)); writeBlock("FN 0: Q217 = " + xyzFormat.format(y)); writeBlock("CYCL CALL"); xOutput.reset(); yOutput.reset(); } } else { writeBlock("L" + xOutput.format(x) + yOutput.format(y) + " FMAX " + mFormat.format(99)); } */ // place cycle operation in subprogram if (cycleSubprogramIsActive) { if (isFirstCyclePoint()) { // call subprogram subprogramCall(); subprogramStart(new Vector(x, y, z), new Vector(0, 0, 0), false); } } writeBlock(gMotionModal.format(0) + xOutput.format(x) + yOutput.format(y) + mFormat.format(99)); if (incrementalMode) { // set current position to clearance height setCyclePosition(cycle.clearance); } } else { expandCyclePoint(x, y, z); cycleSubprogramIsActive = false; } } function onCycleEnd() { if (cycleSubprogramIsActive) { subprogramEnd(); cycleSubprogramIsActive = false; } zOutput.reset(); } var pendingRadiusCompensation = -1; function onRadiusCompensation() { pendingRadiusCompensation = radiusCompensation; } function onRapid(x, y, z) { var xyz = xOutput.format(x) + yOutput.format(y) + zOutput.format(z); if (xyz) { pendingRadiusCompensation = -1; writeBlock(gMotionModal.format(0) + radiusCompensationTable.lookup(radiusCompensation) + xyz); } forceFeed(); } function onLinear(x, y, z, feed) { var xyz = xOutput.format(x) + yOutput.format(y) + zOutput.format(z); var f = getFeed(feed); if (xyz) { pendingRadiusCompensation = -1; writeBlock(gMotionModal.format(1) + radiusCompensationTable.lookup(radiusCompensation) + xyz + f); } else if (f) { if (getNextRecord().isMotion()) { // try not to output feed without motion forceFeed(); // force feed on next line } else { pendingRadiusCompensation = -1; writeBlock(gMotionModal.format(1) + radiusCompensationTable.lookup(radiusCompensation) + f); } } } function onRapid5D(x, y, z, a, b, c) { if (pendingRadiusCompensation >= 0) { error(localize("Radius compensation cannot be activated/deactivated for 5-axis move.")); return; } if (currentSection.isOptimizedForMachine()) { var xyzabc = xOutput.format(x) + yOutput.format(y) + zOutput.format(z) + aOutput.format(a) + bOutput.format(b) + cOutput.format(c); if (xyzabc) { writeBlock(gMotionModal.format(1) + radiusCompensationTable.lookup(radiusCompensation) + xyzabc); } } else { forceXYZ(); // required var pt = xOutput.format(x) + yOutput.format(y) + zOutput.format(z) + txOutput.format(a) + tyOutput.format(b) + tzOutput.format(c); if (pt) { pendingRadiusCompensation = -1; writeBlock("LN" + pt + radiusCompensationTable.lookup(radiusCompensation) + " FMAX"); } } forceFeed(); // force feed on next line } function onLinear5D(x, y, z, a, b, c, feed) { if (pendingRadiusCompensation >= 0) { error(localize("Radius compensation cannot be activated/deactivated for 5-axis move.")); return; } if (currentSection.isOptimizedForMachine()) { var xyzabc = xOutput.format(x) + yOutput.format(y) + zOutput.format(z) + aOutput.format(a) + bOutput.format(b) + cOutput.format(c); var f = getFeed(feed); if (xyzabc) { writeBlock(gMotionModal.format(1) + radiusCompensationTable.lookup(radiusCompensation) + xyzabc + f); } else if (f) { if (getNextRecord().isMotion()) { // try not to output feed without motion forceFeed(); // force feed on next line } else { pendingRadiusCompensation = -1; writeBlock(gMotionModal.format(1) + radiusCompensationTable.lookup(radiusCompensation) + f); } } } else { forceXYZ(); // required var pt = xOutput.format(x) + yOutput.format(y) + zOutput.format(z) + txOutput.format(a) + tyOutput.format(b) + tzOutput.format(c); var f = getFeed(feed); if (pt) { pendingRadiusCompensation = -1; writeBlock("LN" + pt + radiusCompensationTable.lookup(radiusCompensation) + f); } else if (f) { if (getNextRecord().isMotion()) { // try not to output feed without motion forceFeed(); // force feed on next line } else { pendingRadiusCompensation = -1; writeBlock("LN" + radiusCompensationTable.lookup(radiusCompensation) + f); } } } } function onCircular(clockwise, cx, cy, cz, x, y, z, feed) { if (pendingRadiusCompensation >= 0) { error(localize("Radius compensation cannot be activated/deactivated for a circular move.")); return; } if (!getProperty("allowArcs") || isHelical()) { linearize(tolerance); return; } var start = getCurrentPosition(); var f = getFeed(feed); if (isFullCircle()) { switch (getCircularPlane()) { case PLANE_XY: writeBlock(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) + f); break; case PLANE_ZX: writeBlock(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) + f); break; case PLANE_YZ: writeBlock(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) + f); break; default: linearize(tolerance); } } else { switch (getCircularPlane()) { case PLANE_XY: writeBlock(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) + f); break; case PLANE_ZX: writeBlock(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) + f); break; case PLANE_YZ: writeBlock(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) + f); break; default: linearize(tolerance); } } } /** Used for gun drilling. */ function getCoolantCode(coolant) { currentCoolantMode = undefined; return getCoolantCodes(coolant, true); } var currentCoolantMode = COOLANT_OFF; var coolantOff = undefined; function setCoolant(coolant) { var coolantCodes = getCoolantCodes(coolant, false); if (Array.isArray(coolantCodes)) { if (singleLineCoolant) { writeBlock(coolantCodes.join(getWordSeparator())); } else { for (var c in coolantCodes) { writeBlock(coolantCodes[c]); } } return undefined; } return coolantCodes; } function getCoolantCodes(coolant, isGunDrilling) { var multipleCoolantBlocks = new Array(); // create a formatted array to be passed into the outputted line if (!coolants) { error(localize("Coolants have not been defined.")); } if (tool.type == TOOL_PROBE) { // avoid coolant output for probing coolant = COOLANT_OFF; } if (coolant == currentCoolantMode) { return undefined; // coolant is already active } if ((coolant != COOLANT_OFF) && (currentCoolantMode != COOLANT_OFF) && (coolantOff != undefined)) { if (Array.isArray(coolantOff)) { for (var i in coolantOff) { multipleCoolantBlocks.push(coolantOff[i]); } } else { multipleCoolantBlocks.push(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(m[i]); } } else { multipleCoolantBlocks.push(m); } currentCoolantMode = coolant; for (var i in multipleCoolantBlocks) { if (typeof multipleCoolantBlocks[i] == "number") { multipleCoolantBlocks[i] = mFormat.format(multipleCoolantBlocks[i]); } } if (isGunDrilling) { return [m, coolantOff]; } else { return multipleCoolantBlocks; // return the single formatted coolant value } } return undefined; } var mapCommand = { COMMAND_STOP : 0, COMMAND_OPTIONAL_STOP : 1, COMMAND_END : 30, COMMAND_SPINDLE_CLOCKWISE : 3, COMMAND_SPINDLE_COUNTERCLOCKWISE: 4, // COMMAND_START_SPINDLE COMMAND_STOP_SPINDLE : 5 //COMMAND_ORIENTATE_SPINDLE:19, //COMMAND_LOAD_TOOL:6, // do not use //COMMAND_COOLANT_ON, //COMMAND_COOLANT_OFF, //COMMAND_ACTIVATE_SPEED_FEED_SYNCHRONIZATION //COMMAND_DEACTIVATE_SPEED_FEED_SYNCHRONIZATION }; function onCommand(command) { switch (command) { case COMMAND_COOLANT_OFF: setCoolant(COOLANT_OFF); return; case COMMAND_COOLANT_ON: setCoolant(COOLANT_FLOOD); return; case COMMAND_START_SPINDLE: onCommand(tool.clockwise ? COMMAND_SPINDLE_CLOCKWISE : COMMAND_SPINDLE_COUNTERCLOCKWISE); return; case COMMAND_LOCK_MULTI_AXIS: return; case COMMAND_UNLOCK_MULTI_AXIS: return; case COMMAND_START_CHIP_TRANSPORT: return; case COMMAND_STOP_CHIP_TRANSPORT: return; case COMMAND_BREAK_CONTROL: return; case COMMAND_TOOL_MEASURE: return; case COMMAND_PROBE_ON: return; case COMMAND_PROBE_OFF: return; } var stringId = getCommandStringId(command); var mcode = mapCommand[stringId]; if (mcode != undefined) { writeBlock(mFormat.format(mcode)); } else { onUnsupportedCommand(command); } } function writeToolTable() { if (getProperty("writeTools")) { var tools = getToolTable(); if (tools.getNumberOfTools() > 0) { 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; } } } writeComment(localize("Tools")); writeSeparator(); for (var i = 0; i < tools.getNumberOfTools(); ++i) { var tool = tools.getTool(i); var comment = (getProperty("toolAsName") ? "TT" + (tool.description.toUpperCase()) : " T" + tool.number) + " " + localize("D") + "=" + spatialFormat.format(tool.diameter) + conditional(tool.cornerRadius > 0, " " + localize("CR") + "=" + spatialFormat.format(tool.cornerRadius)) + conditional((tool.taperAngle > 0) && (tool.taperAngle < Math.PI), " " + localize("TAPER") + "=" + taperFormat.format(tool.taperAngle) + localize("deg")); // conditional(tool.tipAngle > 0, " " + localize("TIP:") + "=" + taperFormat.format(tool.tipAngle) + localize("deg")); if (zRanges[tool.number]) { comment += " - " + localize("ZMIN") + "=" + xyzFormat.format(zRanges[tool.number].getMinimum()); comment += " - " + localize("ZMAX") + "=" + xyzFormat.format(zRanges[tool.number].getMaximum()); } comment += " - " + getToolTypeName(tool.type); writeComment(comment); } writeSeparator(); } } } function writeDynamics() { writeComment("Dynamic"); if (hasParameter("operation:tolerance")) { writeBlock("Cam_Tol=" + xyzFormat.format(getParameter("operation:tolerance")) + " // CAM tolerance"); } if (hasParameter("operation:verticalStockToLeave")) { writeBlock("Cam_Stock=" + xyzFormat.format(getParameter("operation:verticalStockToLeave")) + " // CAM oversize"); } } function writeToolDescription() { writeln(""); writeComment("--------------------------------------------------------------------------------------------------"); writeComment(" T" + toolFormat.format(tool.number) + ", TT=" + "\"" + (tool.description.toUpperCase()) + "\", ToolData: Dia=" + +xyzFormat.format(tool.diameter) + ", TipR=" + tool.cornerRadius); writeComment("--------------------------------------------------------------------------------------------------"); } function writeRotZero(abc, comment) { writeBlock( "ROTZERO=" + 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)) + conditional(comment, comment) ); } function writeTlmType() { // set TlmType for tool check after operation if (!isLastSection() && (tool.number == getNextSection().getTool().number || conditional(getProperty("toolAsName"), tool.description == getNextSection().getTool().description))) { if (tlmType != 0) { writeBlock("$TlmType=0"); } tlmType = 0; } else { if (tlmType != 1) { writeBlock("$TlmType=1"); } tlmType = 1; } } function writeMeasureTools() { if (writeMeasureTools.caller.name == "onSectionEnd") { var newTool = !isLastSection() && (tool.number != getNextSection().getTool().number || conditional(getProperty("toolAsName"), tool.description != getNextSection().getTool().description)); if (getProperty("measureTools") == "startEnd" && (getProperty("useFilesForSubprograms") || newTool || isLastSection())) { writeln(""); writeComment("Tool check"); writeBlock("IF $TlmType==1"); writeBlock(" TLM"); writeBlock("ENDIF"); writeBlock("IF $TlmType==2"); writeBlock(" TLM -h"); writeBlock("ENDIF"); writeBlock("IF $TlmType==3"); writeBlock(" TLM -fast"); writeBlock("ENDIF"); } } else { if (getProperty("measureTools") != "disabled") { writeComment("Tool measurements"); writeBlock("Tdm -auto // Diameter measurement"); writeBlock("Tlc -auto // Length correction"); writeBlock(" // Measurement in advance, if necessary (length, diameter, etc.)"); writeBlock(" // Tool geometry check"); writeln(""); } } } function onSectionEnd() { 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); writeMeasureTools(); if (getProperty("useFilesForSubprograms")) { setCoolant(COOLANT_OFF); } subprogramEnd(); } } if (isLastSection() || (getNextSection().getTool().number != tool.number)) { setCoolant(COOLANT_OFF); } if (currentSection.isMultiAxis()) { setTCP(false); writeRetract(Z); gMotionModal.reset(); setWorkPlane(new Vector(0, 0, 0), false); } else { if (homeAllAxesAtSectionEnd) { setWorkPlane(new Vector(0, 0, 0), false); } } writeMeasureTools(); invalidate(); } /** Output block to do safe retract and/or move to home position. */ function writeRetract() { var words = []; // store all retracted axes in an array var retractAxes = new Array(false, false, false); var method = getProperty("safePositionMethod"); if (method == "clearanceHeight") { if (!is3D()) { error(localize("Safe retract option 'Clearance Height' is only supported when all operations are along the setup Z-axis.")); } return; } validate(arguments.length != 0, "No axis specified for writeRetract()."); for (i in arguments) { retractAxes[arguments[i]] = true; } if ((retractAxes[0] || retractAxes[1]) && !retracted) { // retract Z first before moving to X/Y home error(localize("Retracting in X/Y is not possible without being retracted in Z.")); return; } // special conditions /* if (retractAxes[2]) { // Z doesn't use G53 method = ""; } */ // define home positions // Roeders does not use coordinates for home positioning /* var _xHome; var _yHome; var _zHome; if (false && method == "G28") { // always use machine home positions _xHome = toPreciseUnit(0, MM); _yHome = toPreciseUnit(0, MM); _zHome = toPreciseUnit(0, MM); } else { _xHome = machineConfiguration.hasHomePositionX() ? machineConfiguration.getHomePositionX() : toPreciseUnit(0, MM); _yHome = machineConfiguration.hasHomePositionY() ? machineConfiguration.getHomePositionY() : toPreciseUnit(0, MM); _zHome = machineConfiguration.getRetractPlane() != 0 ? machineConfiguration.getRetractPlane() : toPreciseUnit(0, MM); } */ for (var i = 0; i < arguments.length; ++i) { switch (arguments[i]) { case X: words.push("SP"); xOutput.reset(); break; case Y: words.push("SP"); yOutput.reset(); break; case Z: if (retractSSA) { words.push("SP -ssa // Approach safety position as starting position"); retractSSA = false; } else { words.push("SP // Safety position"); } zOutput.reset(); retracted = true; break; default: error(localize("Unsupported axis specified for writeRetract().")); return; } } if (words.length > 0) { switch (method) { case "SP": writeBlock(words); break; default: error(localize("Unsupported safe position method.")); return; } } } function onClose() { optionalSection = false; setWorkPlane(new Vector(0, 0, 0), false); writeln(""); onCommand(COMMAND_UNLOCK_MULTI_AXIS); onCommand(COMMAND_STOP_CHIP_TRANSPORT); writeln(""); writeComment(" Reset_Warmup // resetting a temporary warm-up time"); writeComment(" Reset_Offset_R // Initialize 2D-radius correction offset"); writeComment(" $LineUp = 0"); writeln(""); writeln(""); writeComment(" --- End of machining ---"); writeln(""); writeln(""); writeBlock("MDC -End"); writeBlock(mFormat.format(30)); // stop program, spindle stop, coolant off if (subprograms.length > 0) { write(subprograms); } } function setProperty(property, value) { properties[property].current = value; }