diff --git a/RRF Implementation/CalibrateActiveTool.g b/RRF Implementation/CalibrateActiveTool.g new file mode 100644 index 0000000..661907f --- /dev/null +++ b/RRF Implementation/CalibrateActiveTool.g @@ -0,0 +1,146 @@ +; /macros/toolprobe_v3/CalibrateActiveTool.g +; +; Calibrate the currently selected tool's G10 offsets against the located HRP +; tool probe. Uses native G1 H4 throughout. +; +; Preconditions: +; - LocateToolProbe.g has run (tp3_located == true) +; - A tool is selected (state.currentTool != -1) +; +; Result: writes new G10 X/Y/Z offsets for the active tool. +; Endstops are restored on every exit path. + +M98 P"/macros/toolprobe_v3/globals.g" +M98 P"/macros/toolprobe_v3/state.g" + +; Defensive cleanup: in case a previous abort left endstops swapped +M98 P"/macros/toolprobe_v3/_lib/RestoreEndstops.g" + +if !move.axes[0].homed || !move.axes[1].homed || !move.axes[2].homed + abort "CalibrateActiveTool: home all axes first." + +if state.currentTool == -1 + abort "CalibrateActiveTool: select a tool first." + +if !global.tp3_located + abort "CalibrateActiveTool: run LocateToolProbe.g first." + +; Reset babystepping so the staleness check and the calibration both see a +; clean Z reference (and so the per-print Z hand-tuning doesn't bias offsets). +M290 R0 S0 + +M98 P"/macros/toolprobe_v3/_lib/Status.g" S{"toolprobe_v3: calibrating T" ^ state.currentTool} + +; Snapshot current offsets so we apply a CORRECTION (not absolute) +var baseX = tools[state.currentTool].offsets[0] +var baseY = tools[state.currentTool].offsets[1] +var baseZ = tools[state.currentTool].offsets[2] + +; --- Travel near the probe at safe Z --- +; Done BEFORE the staleness check so the Z-frame reading happens at the same +; XY where RefreshProbeZPlane / LocateToolProbe captured it. Otherwise mesh +; height variation between the macro entry XY and the probe XY shows up as a +; false-positive workspace shift. +M98 P"/macros/toolprobe_v3/_lib/MoveToProbeXY.g" + +; --- Staleness check (advisory only) --- +; Approximate workspace Z offset from observable values. Different RRF versions +; report userPosition slightly differently when a tool is selected, so this +; comparison is informational and DOES NOT abort. If you ran autoz/G92 Z/G30 +; since LocateToolProbe and DIDN'T refresh, the calibration will be off by the +; frame delta — the warning below tells you when this is likely. +var currentZFrame = move.axes[2].machinePosition - move.axes[2].userPosition + tools[state.currentTool].offsets[2] +if global.tp3_probeZPlaneFrame > -9998 + if abs(var.currentZFrame - global.tp3_probeZPlaneFrame) > 0.5 + echo "WARNING: workspace Z reference may have shifted since probeZPlane was measured." + echo " Captured frame: " ^ global.tp3_probeZPlaneFrame ^ " Current frame: " ^ var.currentZFrame + echo " If you ran autoz/G92 Z/G30 since LocateToolProbe, T-1 and run RefreshProbeZPlane.g first." + echo " Otherwise this may be benign (RRF version reports userPosition differently with tool active)." + echo " Proceeding with calibration — verify Z offset afterward." + +; --- Discover where the tool tip actually touches the probe --- +; The H4 trigger is physical, so this stops at first contact regardless of how +; far off the existing G10 Z is. Used to set the XY engagement depth so the +; subsequent X/Y scans always engage the dome correctly, even when the tool +; starts well above (or below) the probe due to a rough initial G10 Z. +M98 P"/macros/toolprobe_v3/_lib/Status.g" S"toolprobe_v3: discovering tool tip Z" + +M98 P"/macros/toolprobe_v3/_lib/Probe_IsTriggered.g" +if global.tp3_probeTriggered + M98 P"/macros/toolprobe_v3/_lib/RestoreEndstops.g" + abort "CalibrateActiveTool: probe already triggered at travel Z. Lift tp3_travelZ or check probe." + +M98 P"/macros/toolprobe_v3/_lib/UseProbeAsEndstop.g" A2 + +G91 +G1 H4 Z{-global.tp3_toolDiscoveryPlunge} F{global.tp3_fZFast} +G90 +M400 + +M98 P"/macros/toolprobe_v3/_lib/Probe_IsTriggered.g" +if !global.tp3_probeTriggered + M98 P"/macros/toolprobe_v3/_lib/UseProbeAsEndstop.g" A2 R1 + G1 Z{global.tp3_travelZ} F{global.tp3_fZFast} + echo "CalibrateActiveTool: tool tip plunge of " ^ global.tp3_toolDiscoveryPlunge ^ "mm did not contact probe." + echo "Tool may be much shorter than expected, seed XY may be off, or probe is offline." + echo "Increase tp3_toolDiscoveryPlunge if the tool is very short." + abort "CalibrateActiveTool: tool tip plunge did not contact probe" + +var roughTipZ = move.axes[2].userPosition + +M98 P"/macros/toolprobe_v3/_lib/UseProbeAsEndstop.g" A2 R1 + +; Lift back to safe travel +G1 Z{global.tp3_travelZ} F{global.tp3_fZFast} + +M98 P"/macros/toolprobe_v3/_lib/Status.g" S{"tool tip touched probe at userZ=" ^ var.roughTipZ ^ "; XY engagement Z=" ^ (var.roughTipZ + global.tp3_toolNudgeZOffset)} + +; XY engagement Z relative to the discovered tip touch position. +; toolNudgeZOffset is intentionally shallow (small negative) — tool tips are +; smaller and more fragile than the bare carriage feature used in LocateToolProbe. +var zEngage = var.roughTipZ + global.tp3_toolNudgeZOffset + +; --- Bracket X around expected center --- +M98 P"/macros/toolprobe_v3/_lib/BracketAxis.g" A0 C{global.tp3_probeX} R{global.tp3_edgeStart} Z{var.zEngage} +var cx = global.tp3_lastCenter +var xSpan = global.tp3_lastSpan + +; Move to refined X over expected Y before bracketing Y +G1 Z{global.tp3_travelZ} F{global.tp3_fZFast} +G1 X{var.cx} Y{global.tp3_probeY} F{global.tp3_fXYTravel} + +; --- Bracket Y around expected center --- +M98 P"/macros/toolprobe_v3/_lib/BracketAxis.g" A1 C{global.tp3_probeY} R{global.tp3_edgeStart} Z{var.zEngage} +var cy = global.tp3_lastCenter +var ySpan = global.tp3_lastSpan + +; Span sanity (looser than LocateToolProbe; we already trust the located center) +if abs(var.xSpan - var.ySpan) > global.tp3_spanMatchTol + M98 P"/macros/toolprobe_v3/_lib/RestoreEndstops.g" + abort "CalibrateActiveTool: span asymmetry. X=" ^ var.xSpan ^ " Y=" ^ var.ySpan + +; --- Z touch at refined center --- +G1 Z{global.tp3_travelZ} F{global.tp3_fZFast} +G1 X{var.cx} Y{var.cy} F{global.tp3_fXYTravel} +G1 Z{global.tp3_workcellZ} F{global.tp3_fZFast} + +M98 P"/macros/toolprobe_v3/_lib/TouchZNative.g" +var cz = global.tp3_lastZ + +; --- Apply correction to existing offsets --- +var corrX = global.tp3_probeX - var.cx +var corrY = global.tp3_probeY - var.cy +var corrZ = global.tp3_probeZPlane - var.cz + +var newX = var.baseX + var.corrX +var newY = var.baseY + var.corrY +var newZ = var.baseZ + var.corrZ + +G10 P{state.currentTool} X{var.newX} Y{var.newY} Z{var.newZ} + +; --- Lift, restore, report --- +G1 Z{global.tp3_travelZ} F{global.tp3_fZFast} +M98 P"/macros/toolprobe_v3/_lib/RestoreEndstops.g" + +M98 P"/macros/toolprobe_v3/_lib/Status.g" S{"T" ^ state.currentTool ^ " offsets X=" ^ var.newX ^ " Y=" ^ var.newY ^ " Z=" ^ var.newZ} +M98 P"/macros/toolprobe_v3/_lib/Status.g" S{"T" ^ state.currentTool ^ " delta X=" ^ var.corrX ^ " Y=" ^ var.corrY ^ " Z=" ^ var.corrZ} diff --git a/RRF Implementation/CalibrateToolRange.g b/RRF Implementation/CalibrateToolRange.g new file mode 100644 index 0000000..b4170a6 --- /dev/null +++ b/RRF Implementation/CalibrateToolRange.g @@ -0,0 +1,45 @@ +; /macros/toolprobe_v3/CalibrateToolRange.g +; +; Iterate a range of tools and calibrate each via CalibrateActiveTool.g. +; +; Params: +; start = first tool index (default 0) +; end = last tool index (default 0) +; +; Preconditions: +; - LocateToolProbe.g has run (tp3_located == true) +; +; Endstops are restored after each tool and at the end (and CalibrateActiveTool +; itself restores on every exit, so a failure on one tool does not leave the +; machine in a bad state). + +M98 P"/macros/toolprobe_v3/globals.g" +M98 P"/macros/toolprobe_v3/state.g" +M98 P"/macros/toolprobe_v3/_lib/RestoreEndstops.g" + +if !global.tp3_located + abort "CalibrateToolRange: run LocateToolProbe.g first." + +var start = exists(param.start) ? floor(param.start) : 0 +var end = exists(param.end) ? floor(param.end) : 0 + +if var.start > var.end + abort "CalibrateToolRange: start (" ^ var.start ^ ") > end (" ^ var.end ^ ")" + +M98 P"/macros/toolprobe_v3/_lib/Status.g" S{"toolprobe_v3: calibrating tools T" ^ var.start ^ ".." ^ var.end} + +while var.start <= var.end + if var.start >= #tools + M98 P"/macros/toolprobe_v3/_lib/Status.g" S{"T" ^ var.start ^ " not defined, skipping"} + else + T{var.start} + if state.currentTool != var.start + M98 P"/macros/toolprobe_v3/_lib/Status.g" S{"T" ^ var.start ^ " select failed, skipping"} + else + M98 P"/macros/toolprobe_v3/CalibrateActiveTool.g" + + set var.start = var.start + 1 + +T-1 +M98 P"/macros/toolprobe_v3/_lib/RestoreEndstops.g" +M98 P"/macros/toolprobe_v3/_lib/Status.g" S"toolprobe_v3: tool range calibration complete" diff --git a/RRF Implementation/LocateToolProbe.g b/RRF Implementation/LocateToolProbe.g new file mode 100644 index 0000000..731a79c --- /dev/null +++ b/RRF Implementation/LocateToolProbe.g @@ -0,0 +1,118 @@ +; /macros/toolprobe_v3/LocateToolProbe.g +; +; Locate the fixed (HRP) tool probe XY center and Z plane in the machine frame. +; Uses native G1 H4 probing throughout, with deterministic span / repeatability +; validation borrowed from the v2 design. +; +; Preconditions: +; - All axes homed +; - T-1 (no tool selected) +; +; Result globals (machine frame, T-1): +; global.tp3_probeX, global.tp3_probeY, global.tp3_probeZPlane, global.tp3_located = true +; +; Endstops are restored on every exit path (success or abort). + +M98 P"/macros/toolprobe_v3/globals.g" +M98 P"/macros/toolprobe_v3/state.g" +M98 P"/macros/toolprobe_v3/_lib/EnsureSafeStart.g" + +; Reset babystepping so the captured Z frame is on the unbiased reference +M290 R0 S0 + +M98 P"/macros/toolprobe_v3/_lib/Status.g" S"toolprobe_v3: locating fixed probe" + +; --- Travel to seed XY --- +M98 P"/macros/toolprobe_v3/_lib/MoveToProbeXY.g" + +; --- Discover the probe top via Z plunge --- +M98 P"/macros/toolprobe_v3/_lib/DiscoverProbeZ.g" +; Engage tp3_locateEngagementDepth mm BELOW the discovered touch (carriage +; geometry knob — see UserConfig.g 'CARRIAGE GEOMETRY' section). +var zEngage = global.tp3_discoveredEngageZ - global.tp3_locateEngagementDepth + +; ============================================================================ +; PASS 1: bracket around the seed +; ============================================================================ +M98 P"/macros/toolprobe_v3/_lib/Status.g" S"toolprobe_v3: pass 1 (coarse)" + +M98 P"/macros/toolprobe_v3/_lib/BracketAxis.g" A0 C{global.tp3_probeX} R{global.tp3_edgeStart} Z{var.zEngage} +var cx1 = global.tp3_lastCenter +var xSpan = global.tp3_lastSpan + +; Move to refined X over seed Y before Y bracket +G1 Z{global.tp3_travelZ} F{global.tp3_fZFast} +G1 X{var.cx1} Y{global.tp3_probeY} F{global.tp3_fXYTravel} + +M98 P"/macros/toolprobe_v3/_lib/BracketAxis.g" A1 C{global.tp3_probeY} R{global.tp3_edgeStart} Z{var.zEngage} +var cy1 = global.tp3_lastCenter +var ySpan = global.tp3_lastSpan + +; --- Span validation --- +if var.xSpan < global.tp3_spanMin || var.xSpan > global.tp3_spanMax + M98 P"/macros/toolprobe_v3/_lib/RestoreEndstops.g" + abort "LocateToolProbe: X span out of range: " ^ var.xSpan + +if var.ySpan < global.tp3_spanMin || var.ySpan > global.tp3_spanMax + M98 P"/macros/toolprobe_v3/_lib/RestoreEndstops.g" + abort "LocateToolProbe: Y span out of range: " ^ var.ySpan + +if abs(var.xSpan - var.ySpan) > global.tp3_spanMatchTol + M98 P"/macros/toolprobe_v3/_lib/RestoreEndstops.g" + abort "LocateToolProbe: span asymmetry. X=" ^ var.xSpan ^ " Y=" ^ var.ySpan + +; ============================================================================ +; PASS 2: refine around the discovered center +; ============================================================================ +M98 P"/macros/toolprobe_v3/_lib/Status.g" S"toolprobe_v3: pass 2 (refine)" + +var rx = (var.xSpan / 2) + global.tp3_refineMargin +var ry = (var.ySpan / 2) + global.tp3_refineMargin + +G1 Z{global.tp3_travelZ} F{global.tp3_fZFast} +G1 X{var.cx1} Y{var.cy1} F{global.tp3_fXYTravel} + +M98 P"/macros/toolprobe_v3/_lib/BracketAxis.g" A0 C{var.cx1} R{var.rx} Z{var.zEngage} +var cx2 = global.tp3_lastCenter + +G1 Z{global.tp3_travelZ} F{global.tp3_fZFast} +G1 X{var.cx2} Y{var.cy1} F{global.tp3_fXYTravel} + +M98 P"/macros/toolprobe_v3/_lib/BracketAxis.g" A1 C{var.cy1} R{var.ry} Z{var.zEngage} +var cy2 = global.tp3_lastCenter + +; --- Center repeatability check --- +var dxc = abs(var.cx2 - var.cx1) +var dyc = abs(var.cy2 - var.cy1) +if var.dxc > global.tp3_centerRepeatTol || var.dyc > global.tp3_centerRepeatTol + M98 P"/macros/toolprobe_v3/_lib/RestoreEndstops.g" + abort "LocateToolProbe: center not repeatable. Δx=" ^ var.dxc ^ " Δy=" ^ var.dyc + +; ============================================================================ +; FINAL Z TOUCH at refined center +; ============================================================================ +M98 P"/macros/toolprobe_v3/_lib/Status.g" S"toolprobe_v3: final Z touch" + +G1 Z{global.tp3_travelZ} F{global.tp3_fZFast} +G1 X{var.cx2} Y{var.cy2} F{global.tp3_fXYTravel} +G1 Z{global.tp3_workcellZ} F{global.tp3_fZFast} + +M98 P"/macros/toolprobe_v3/_lib/TouchZNative.g" +var cz = global.tp3_lastZ + +; --- Save located probe --- +; Capture the workspace Z offset that was active when probeZPlane was measured. +; CalibrateActiveTool uses this to detect "autoz happened since locate" and +; demand a RefreshProbeZPlane.g run before producing wrong Z calibrations. +; With T-1 active, workplace Z offset = machinePosition - userPosition. +set global.tp3_probeX = var.cx2 +set global.tp3_probeY = var.cy2 +set global.tp3_probeZPlane = var.cz +set global.tp3_probeZPlaneFrame = move.axes[2].machinePosition - move.axes[2].userPosition +set global.tp3_located = true + +; --- Lift, restore, report --- +G1 Z{global.tp3_travelZ} F{global.tp3_fZFast} +M98 P"/macros/toolprobe_v3/_lib/RestoreEndstops.g" + +M98 P"/macros/toolprobe_v3/_lib/Status.g" S{"toolprobe_v3: located X=" ^ global.tp3_probeX ^ " Y=" ^ global.tp3_probeY ^ " Z=" ^ global.tp3_probeZPlane} diff --git a/RRF Implementation/RefreshProbeZPlane.g b/RRF Implementation/RefreshProbeZPlane.g new file mode 100644 index 0000000..c277b60 --- /dev/null +++ b/RRF Implementation/RefreshProbeZPlane.g @@ -0,0 +1,55 @@ +; /macros/toolprobe_v3/RefreshProbeZPlane.g +; +; Re-measure the located probe's Z plane in the CURRENT user frame. Run this +; after any operation that changes the workplace Z offset (autoz, manual G92 Z, +; G30 to set Z, etc.) so subsequent CalibrateActiveTool runs have a Z reference +; in the new frame. +; +; XY are unaffected by autoz (autoz only does G92 Z), so tp3_probeX/probeY are +; preserved. +; +; Preconditions: +; - All axes homed +; - T-1 (no tool selected) +; - LocateToolProbe.g has been run (tp3_located == true) +; +; Recommended order of operations: +; 1. T-1 +; 2. M98 P"/macros/toolprobe_v3/LocateToolProbe.g" +; 3. (autoz / klicky calibration here) +; 4. T-1 +; 5. M98 P"/macros/toolprobe_v3/RefreshProbeZPlane.g" +; 6. T0 (or any tool) +; 7. M98 P"/macros/toolprobe_v3/CalibrateActiveTool.g" + +M98 P"/macros/toolprobe_v3/globals.g" +M98 P"/macros/toolprobe_v3/state.g" +M98 P"/macros/toolprobe_v3/_lib/EnsureSafeStart.g" + +if !global.tp3_located + abort "RefreshProbeZPlane: run LocateToolProbe.g first." + +; Reset babystepping so the captured Z frame is on the unbiased reference +M290 R0 S0 + +M98 P"/macros/toolprobe_v3/_lib/Status.g" S"toolprobe_v3: refreshing probe Z plane in current user frame" + +; --- Travel to the located XY at safe Z, then drop near probe --- +G90 +G1 Z{global.tp3_travelZ} F{global.tp3_fZFast} +G1 X{global.tp3_probeX} Y{global.tp3_probeY} F{global.tp3_fXYTravel} +G1 Z{global.tp3_workcellZ} F{global.tp3_fZFast} + +; --- Precision Z touch (slow plunge with backoff) --- +M98 P"/macros/toolprobe_v3/_lib/TouchZNative.g" + +; --- Update probeZPlane and the captured workspace frame --- +; With T-1 active, workplace Z offset = machinePosition - userPosition. +set global.tp3_probeZPlane = global.tp3_lastZ +set global.tp3_probeZPlaneFrame = move.axes[2].machinePosition - move.axes[2].userPosition + +; --- Lift, restore, report --- +G1 Z{global.tp3_travelZ} F{global.tp3_fZFast} +M98 P"/macros/toolprobe_v3/_lib/RestoreEndstops.g" + +M98 P"/macros/toolprobe_v3/_lib/Status.g" S{"toolprobe_v3: probeZPlane=" ^ global.tp3_probeZPlane ^ " (workspace Z offset=" ^ global.tp3_probeZPlaneFrame ^ ")"} diff --git a/RRF Implementation/UserConfig.g b/RRF Implementation/UserConfig.g new file mode 100644 index 0000000..7264b9e --- /dev/null +++ b/RRF Implementation/UserConfig.g @@ -0,0 +1,164 @@ +; /macros/toolprobe_v3/UserConfig.g +; +; Operator-editable tuning for toolprobe_v3. +; Edit the values below, then run this file to apply. It updates tunables and +; SEED guesses but never overwrites the located probe XY/Z unless you flip +; the resetEstimateToSeed switch. + +; ============================================================================= +; OPTIONAL: reset runtime estimate to seed +; ============================================================================= +; Set true once when you want LocateToolProbe to start from a fresh seed. +; After a successful run, set back to false. +var resetEstimateToSeed = false + + +; ============================================================================= +; *** CARRIAGE GEOMETRY — read this first *** +; ============================================================================= +; LocateToolProbe (T-1) uses your BARE CARRIAGE to bracket the probe dome. +; After the first downward touch, the carriage drops this many mm further so +; the carriage's contact feature can engage the dome's SIDE for the X/Y scans. +; Pick the value that matches your hardware: +; +; - Nudge / probe peg sticking 5+mm below the carriage: 1.0 - 1.5 +; - Small contact pin (1-2mm below the carriage body): 0.3 - 0.7 +; - Flat carriage bottom, no dedicated probe feature: 0.0 - 0.1 +; +; Symptom -> too large: LocateToolProbe aborts with +; "ScanEdgeNative: probe already triggered at scan start" +; (the carriage is being pushed past where it can physically go). +; Symptom -> too small: LocateToolProbe aborts with +; "probe did not trigger within 12mm scan" +; (the contact feature isn't engaged with the dome's side). +var locateEngagementDepth = 0.5 + +; CalibrateActiveTool engagement (tool tip touches dome's side at this depth) +; Negative = below the discovered tip-touch point. Keep shallow for tool tips. +var toolNudgeZOffset = -0.20 + + +; ============================================================================= +; SEED VALUES (rough estimates, machine frame, T-1) +; ============================================================================= +var seedX = 263.8675 +var seedY = 309.9875 +var seedZGuess = 4.140 +var domeZ = 0.5 + + +; ============================================================================= +; PROBE SELECTION +; ============================================================================= +var probeIndex = 3 +var trigMin = 900 +var trigMax = 1100 + + +; ============================================================================= +; ENDSTOP PINS (must match config.g) +; ============================================================================= +var endstopPinX = "^io2" +var endstopPinY = "^io1" + + +; ============================================================================= +; Z POLICY +; ============================================================================= +var travelZ = 15 +var workcellZ = 8 +var betweenTouchZLift = 0.5 +; locateEngagementDepth and toolNudgeZOffset live in the CARRIAGE GEOMETRY +; section near the top of this file. + + +; ============================================================================= +; XY GEOMETRY / VALIDATION +; ============================================================================= +var edgeStart = 6.0 +var refineMargin = 0.5 + +var spanMin = 1.0 +var spanMax = 12.0 +var spanMatchTol = 1.0 +var centerRepeatTol = 0.05 + + +; ============================================================================= +; Z TOUCH +; ============================================================================= +var zFastPlunge = 10.0 +var zSlowPlunge = 2.0 +var zBackoff = 1.0 + + +; ============================================================================= +; FEEDRATES +; ============================================================================= +var fZFast = 600 +var fZSlow = 50 +var fXYTravel = 6000 +var fXYScan = 50 + + +; ============================================================================= +; DOCK BAND +; ============================================================================= +var dockYMin = 9999 ; set <= dockYMax to enable +var dockYMax = -9999 +var corridorY = 150 + + +; ============================================================================= +; APPLY (create-if-missing, else set) +; ============================================================================= +M98 P"/macros/toolprobe_v3/globals.g" +M98 P"/macros/toolprobe_v3/state.g" + +set global.tp3_probeSeedX = var.seedX +set global.tp3_probeSeedY = var.seedY +set global.tp3_probeSeedZGuess = var.seedZGuess +set global.tp3_probeDomeZ = var.domeZ + +set global.tp3_probeIndex = var.probeIndex +set global.tp3_probeTrigMin = var.trigMin +set global.tp3_probeTrigMax = var.trigMax + +set global.tp3_endstopPinX = var.endstopPinX +set global.tp3_endstopPinY = var.endstopPinY + +set global.tp3_travelZ = var.travelZ +set global.tp3_workcellZ = var.workcellZ +set global.tp3_betweenTouchZLift = var.betweenTouchZLift +set global.tp3_locateEngagementDepth = var.locateEngagementDepth +set global.tp3_toolNudgeZOffset = var.toolNudgeZOffset + +set global.tp3_edgeStart = var.edgeStart +set global.tp3_refineMargin = var.refineMargin + +set global.tp3_spanMin = var.spanMin +set global.tp3_spanMax = var.spanMax +set global.tp3_spanMatchTol = var.spanMatchTol +set global.tp3_centerRepeatTol = var.centerRepeatTol + +set global.tp3_zFastPlunge = var.zFastPlunge +set global.tp3_zSlowPlunge = var.zSlowPlunge +set global.tp3_zBackoff = var.zBackoff + +set global.tp3_fZFast = var.fZFast +set global.tp3_fZSlow = var.fZSlow +set global.tp3_fXYTravel = var.fXYTravel +set global.tp3_fXYScan = var.fXYScan + +set global.tp3_dockYMin = var.dockYMin +set global.tp3_dockYMax = var.dockYMax +set global.tp3_corridorY = var.corridorY + +if var.resetEstimateToSeed + set global.tp3_probeX = var.seedX + set global.tp3_probeY = var.seedY + set global.tp3_probeZPlane = var.seedZGuess + set global.tp3_located = false + M118 P0 S"toolprobe_v3: estimate reset to seed (tp3_located=false)" +else + M118 P0 S"toolprobe_v3: tunables applied (estimate preserved)" diff --git a/RRF Implementation/_lib/BracketAxis.g b/RRF Implementation/_lib/BracketAxis.g new file mode 100644 index 0000000..de38ee4 --- /dev/null +++ b/RRF Implementation/_lib/BracketAxis.g @@ -0,0 +1,37 @@ +; /macros/toolprobe_v3/_lib/BracketAxis.g +; +; Bracket the dome on one axis: scan from -R to find the minus-side edge, +; then scan from +R to find the plus-side edge. Returns center and span. +; +; Params: +; A = axis (0 = X, 1 = Y) +; C = center estimate (machine frame) +; R = half-window: start scans this far from C +; Z = engagement Z (machine frame) +; +; Outputs: +; global.tp3_lastCenter +; global.tp3_lastSpan + +M98 P"/macros/toolprobe_v3/globals.g" +M98 P"/macros/toolprobe_v3/state.g" + +if !exists(param.A) || !exists(param.C) || !exists(param.R) || !exists(param.Z) + abort "BracketAxis: requires A, C, R, Z" + +; Minus-side scan: start at C - R, scan in +1 direction +M98 P"/macros/toolprobe_v3/_lib/ScanEdgeNative.g" A{param.A} D1 S{param.C - param.R} Z{param.Z} +var minus = global.tp3_lastEdge + +; Plus-side scan: start at C + R, scan in -1 direction +M98 P"/macros/toolprobe_v3/_lib/ScanEdgeNative.g" A{param.A} D-1 S{param.C + param.R} Z{param.Z} +var plus = global.tp3_lastEdge + +set global.tp3_lastSpan = var.plus - var.minus +set global.tp3_lastCenter = (var.plus + var.minus) / 2 + +if global.tp3_lastSpan <= 0 + abort "BracketAxis: invalid span. minus=" ^ var.minus ^ " plus=" ^ var.plus + +var axisName = (param.A == 0) ? "X" : "Y" +M98 P"/macros/toolprobe_v3/_lib/Status.g" S{"bracket " ^ var.axisName ^ ": center=" ^ global.tp3_lastCenter ^ ", span=" ^ global.tp3_lastSpan} diff --git a/RRF Implementation/_lib/DiscoverProbeZ.g b/RRF Implementation/_lib/DiscoverProbeZ.g new file mode 100644 index 0000000..7ccf8e3 --- /dev/null +++ b/RRF Implementation/_lib/DiscoverProbeZ.g @@ -0,0 +1,54 @@ +; /macros/toolprobe_v3/_lib/DiscoverProbeZ.g +; +; Find the probe top via a single native G1 H4 plunge from travelZ. +; Output: +; global.tp3_discoveredEngageZ = userPosition at first contact (tip frame) +; +; The caller (LocateToolProbe.g) is responsible for adding any further +; engagement depth via tp3_locateEngagementDepth. +; +; Assumes you are already positioned at (tp3_probeX, tp3_probeY). + +M98 P"/macros/toolprobe_v3/globals.g" +M98 P"/macros/toolprobe_v3/state.g" + +M98 P"/macros/toolprobe_v3/_lib/Status.g" S"toolprobe_v3: discovering probe Z plane" + +; Verify we are not already triggered before plunging +M98 P"/macros/toolprobe_v3/_lib/Probe_IsTriggered.g" +if global.tp3_probeTriggered + abort "DiscoverProbeZ: probe already triggered at travel Z (raise tp3_travelZ or check probe state)" + +; Lift to safe Z first. No G53 — with T-1 it makes no difference, and dropping +; G53 keeps this leaf consistent with the T-active context. +G90 +G1 Z{global.tp3_travelZ} F{global.tp3_fZFast} +M400 + +; Assign probe as Z endstop, native H4 plunge, then restore Z endstop +M98 P"/macros/toolprobe_v3/_lib/UseProbeAsEndstop.g" A2 + +; Plunge from travelZ down toward 0 — H4 stops on trigger +G1 H4 Z0 F{global.tp3_fZFast} +M400 + +; Capture in tool-tip frame (userPosition). With T-1 this equals +; machinePosition; with T-active (not the normal call site) it would be tip Z. +var touchZ = move.axes[2].userPosition + +M98 P"/macros/toolprobe_v3/_lib/UseProbeAsEndstop.g" A2 R1 + +; Sanity: we should not have run all the way to Z0 +if var.touchZ <= 0.05 + abort "DiscoverProbeZ: plunge ran to Z0 without trigger. Seed XY likely off, or probe failed." + +; Lift back to safe Z +G1 Z{global.tp3_travelZ} F{global.tp3_fZFast} +M400 + +; Store the discovered touch Z. The caller adds tp3_locateEngagementDepth. +; Note: tp3_probeZPlane is deliberately NOT set here — LocateToolProbe's final +; TouchZNative is the single source of truth for that value. +set global.tp3_discoveredEngageZ = var.touchZ + +M98 P"/macros/toolprobe_v3/_lib/Status.g" S{"toolprobe_v3: probe top Z=" ^ var.touchZ} diff --git a/RRF Implementation/_lib/EnsureSafeStart.g b/RRF Implementation/_lib/EnsureSafeStart.g new file mode 100644 index 0000000..f67ac45 --- /dev/null +++ b/RRF Implementation/_lib/EnsureSafeStart.g @@ -0,0 +1,14 @@ +; /macros/toolprobe_v3/_lib/EnsureSafeStart.g +; Common pre-flight for top-level toolprobe_v3 entries. +; +; - Restores any stale endstop swap from a previous aborted run +; - Verifies XYZ are homed +; - Verifies T-1 (no tool selected) + +M98 P"/macros/toolprobe_v3/_lib/RestoreEndstops.g" + +if !move.axes[0].homed || !move.axes[1].homed || !move.axes[2].homed + abort "toolprobe_v3: home all axes first." + +if state.currentTool != -1 + abort "toolprobe_v3: deselect tool first (T-1)." diff --git a/RRF Implementation/_lib/MoveToProbeXY.g b/RRF Implementation/_lib/MoveToProbeXY.g new file mode 100644 index 0000000..cf0148d --- /dev/null +++ b/RRF Implementation/_lib/MoveToProbeXY.g @@ -0,0 +1,28 @@ +; /macros/toolprobe_v3/_lib/MoveToProbeXY.g +; Safe travel to (tp3_probeX, tp3_probeY) at travelZ, with optional dock-band +; avoidance routing. Caller drops Z afterward. + +M98 P"/macros/toolprobe_v3/globals.g" +M98 P"/macros/toolprobe_v3/state.g" + +; Note: no G53 — with workplace offsets at 0 and a tool selected, user-frame +; moves correctly position the TOOL TIP (not the carriage) at the probe XY. +; G53 would crash a tool extending below the carriage at travelZ. +; +; Dock-band routing assumption: with T-active, the tool's Y offset is small +; relative to (corridorY - dockYMin/Max). Typical Jubilee setups satisfy this. +G90 +G1 Z{global.tp3_travelZ} F{global.tp3_fZFast} + +var routed = false +if global.tp3_dockYMin <= global.tp3_dockYMax + var nowInBand = (move.axes[1].userPosition >= global.tp3_dockYMin) && (move.axes[1].userPosition <= global.tp3_dockYMax) + var tgtInBand = (global.tp3_probeY >= global.tp3_dockYMin) && (global.tp3_probeY <= global.tp3_dockYMax) + if var.nowInBand || var.tgtInBand + G1 Y{global.tp3_corridorY} F{global.tp3_fXYTravel} + G1 X{global.tp3_probeX} F{global.tp3_fXYTravel} + G1 Y{global.tp3_probeY} F{global.tp3_fXYTravel} + set var.routed = true + +if !var.routed + G1 X{global.tp3_probeX} Y{global.tp3_probeY} F{global.tp3_fXYTravel} diff --git a/RRF Implementation/_lib/Probe_IsTriggered.g b/RRF Implementation/_lib/Probe_IsTriggered.g new file mode 100644 index 0000000..2e980dc --- /dev/null +++ b/RRF Implementation/_lib/Probe_IsTriggered.g @@ -0,0 +1,12 @@ +; /macros/toolprobe_v3/_lib/Probe_IsTriggered.g +; Status query (no motion). Sets global.tp3_probeTriggered based on the probe +; reading. Used to verify untriggered start state, NOT as a probing primitive. +; All actual probing is done with native G1 H4 moves. + +M98 P"/macros/toolprobe_v3/globals.g" + +if !exists(global.tp3_probeTriggered) + global tp3_probeTriggered = false + +var v = sensors.probes[global.tp3_probeIndex].value[0] +set global.tp3_probeTriggered = (var.v >= global.tp3_probeTrigMin) && (var.v <= global.tp3_probeTrigMax) diff --git a/RRF Implementation/_lib/RestoreEndstops.g b/RRF Implementation/_lib/RestoreEndstops.g new file mode 100644 index 0000000..4623454 --- /dev/null +++ b/RRF Implementation/_lib/RestoreEndstops.g @@ -0,0 +1,8 @@ +; /macros/toolprobe_v3/_lib/RestoreEndstops.g +; Defensive full restore of XYZ endstop configuration. Called at the start of +; top-level macros (in case a previous run aborted with endstops swapped) and +; at the end of every top-level macro. + +M98 P"/macros/toolprobe_v3/_lib/UseProbeAsEndstop.g" A0 R1 +M98 P"/macros/toolprobe_v3/_lib/UseProbeAsEndstop.g" A1 R1 +M98 P"/macros/toolprobe_v3/_lib/UseProbeAsEndstop.g" A2 R1 diff --git a/RRF Implementation/_lib/ScanEdgeNative.g b/RRF Implementation/_lib/ScanEdgeNative.g new file mode 100644 index 0000000..070eae6 --- /dev/null +++ b/RRF Implementation/_lib/ScanEdgeNative.g @@ -0,0 +1,95 @@ +; /macros/toolprobe_v3/_lib/ScanEdgeNative.g +; +; Single-axis edge scan using native G1 H4 probing. The probe is assigned as +; the endstop for ONLY this axis for the duration of the scan, then restored +; immediately after the move completes. +; +; Params: +; A = axis (0 = X, 1 = Y) +; D = direction of scan motion (+1 or -1) +; S = absolute START coordinate on that axis (machine frame; should be +; offset AWAY from the expected edge so the move starts untriggered) +; Z = engagement Z (machine frame) +; +; Output: +; global.tp3_lastEdge = machine-frame coordinate where the probe tripped + +M98 P"/macros/toolprobe_v3/globals.g" +M98 P"/macros/toolprobe_v3/state.g" + +if !exists(param.A) || !exists(param.D) || !exists(param.S) || !exists(param.Z) + abort "ScanEdgeNative: requires A, D, S, Z" + +var axisIsX = (param.A == 0) +var dir = (param.D > 0) ? 1 : -1 +var startCoord = param.S +var zEngage = param.Z + +; Total scan window: from start, scan up to 2 * edgeStart through center +var maxScan = 2 * global.tp3_edgeStart + +; --- Move to start at safe Z --- +; Note: no G53 — with workplace offsets at 0, user-frame moves give the same +; machine positions when T-1 AND correctly target the tool tip when T-active. +; G53 here would crash a tool extending below the carriage, and would ignore +; tool offsets when bracketing the dome. +G90 +G1 Z{global.tp3_travelZ} F{global.tp3_fZFast} +if var.axisIsX + G1 X{var.startCoord} F{global.tp3_fXYTravel} +else + G1 Y{var.startCoord} F{global.tp3_fXYTravel} + +; --- Drop to engagement Z --- +G1 Z{var.zEngage} F{global.tp3_fZFast} +M400 +G4 P100 ; settle + +; --- Verify untriggered start --- +M98 P"/macros/toolprobe_v3/_lib/Probe_IsTriggered.g" +if global.tp3_probeTriggered + ; Lift before erroring so retry is safer + G1 Z{global.tp3_travelZ} F{global.tp3_fZFast} + echo "ScanEdgeNative: probe already triggered at scan start. zEngage=" ^ var.zEngage + echo "Contact feature cannot dive to engagement depth." + echo "T-1 (LocateToolProbe): reduce tp3_locateEngagementDepth in UserConfig.g." + echo "T-active (CalibrateActiveTool): raise tp3_toolNudgeZOffset toward 0." + abort "ScanEdgeNative: contact feature cannot reach engagement depth" + +; --- Native H4 scan --- +M98 P"/macros/toolprobe_v3/_lib/UseProbeAsEndstop.g" A{param.A} + +G91 +if var.axisIsX + G1 H4 X{var.dir * var.maxScan} F{global.tp3_fXYScan} +else + G1 H4 Y{var.dir * var.maxScan} F{global.tp3_fXYScan} +G90 +M400 ; ensure motion finished and OM updated + +; --- Capture stop position --- +; userPosition reflects the TOOL TIP position (when a tool is selected) and +; equals machinePosition when T-1. Using userPosition makes the offset formula +; in CalibrateActiveTool come out correct in both contexts. +var hitPos = var.axisIsX ? move.axes[0].userPosition : move.axes[1].userPosition + +; --- Restore endstop for this axis immediately --- +M98 P"/macros/toolprobe_v3/_lib/UseProbeAsEndstop.g" A{param.A} R1 + +; --- Did the move actually trigger, or did it run to full travel? --- +var traveled = (var.hitPos - var.startCoord) * var.dir +if var.traveled >= (var.maxScan - 0.005) + ; Lift before erroring + G1 Z{global.tp3_travelZ} F{global.tp3_fZFast} + abort "ScanEdgeNative: probe did not trigger within " ^ var.maxScan ^ "mm scan." + +set global.tp3_lastEdge = var.hitPos + +; --- Lift after touch so cross moves don't drag --- +G91 +G1 Z{global.tp3_betweenTouchZLift} F{global.tp3_fZFast} +G90 + +var axisName = var.axisIsX ? "X" : "Y" +var dirName = (var.dir > 0) ? "+" : "-" +M98 P"/macros/toolprobe_v3/_lib/Status.g" S{"edge " ^ var.axisName ^ var.dirName ^ " = " ^ var.hitPos} diff --git a/RRF Implementation/_lib/Status.g b/RRF Implementation/_lib/Status.g new file mode 100644 index 0000000..17c43a6 --- /dev/null +++ b/RRF Implementation/_lib/Status.g @@ -0,0 +1,11 @@ +; /macros/toolprobe_v3/_lib/Status.g +; Push a status line to all DWC clients AND the firmware console. +; +; Usage: +; M98 P"/macros/toolprobe_v3/_lib/Status.g" S"toolprobe_v3: locating fixed probe" + +if !exists(param.S) + abort "Status.g: requires S" + +M118 P0 S{param.S} +echo {param.S} diff --git a/RRF Implementation/_lib/TouchZNative.g b/RRF Implementation/_lib/TouchZNative.g new file mode 100644 index 0000000..c2fd1a6 --- /dev/null +++ b/RRF Implementation/_lib/TouchZNative.g @@ -0,0 +1,68 @@ +; /macros/toolprobe_v3/_lib/TouchZNative.g +; +; Native G1 H4 Z touch: untriggered-check -> fast plunge -> backoff -> +; slow plunge. Records the slow trigger position. +; +; Caller must already have positioned the head at (probeX, probeY, workcellZ) +; with the probe untriggered. +; +; Output: +; global.tp3_lastZ = machine-frame Z coord at slow trigger + +M98 P"/macros/toolprobe_v3/globals.g" +M98 P"/macros/toolprobe_v3/state.g" + +; --- Verify untriggered start --- +M98 P"/macros/toolprobe_v3/_lib/Probe_IsTriggered.g" +if global.tp3_probeTriggered + abort "TouchZNative: probe already triggered. Raise tp3_workcellZ." + +; --- Assign Z probe --- +M98 P"/macros/toolprobe_v3/_lib/UseProbeAsEndstop.g" A2 + +; --- Fast plunge --- +G91 +G1 H4 Z{-global.tp3_zFastPlunge} F{global.tp3_fZFast} +G90 +M400 + +; H4 stops on trigger; sanity check +M98 P"/macros/toolprobe_v3/_lib/Probe_IsTriggered.g" +if !global.tp3_probeTriggered + M98 P"/macros/toolprobe_v3/_lib/UseProbeAsEndstop.g" A2 R1 + abort "TouchZNative: fast plunge ran out without trigger. Lower tp3_workcellZ or raise tp3_zFastPlunge." + +; --- Backoff to release contact --- +G91 +G1 Z{global.tp3_zBackoff} F{global.tp3_fZFast} +G90 +M400 + +M98 P"/macros/toolprobe_v3/_lib/Probe_IsTriggered.g" +if global.tp3_probeTriggered + M98 P"/macros/toolprobe_v3/_lib/UseProbeAsEndstop.g" A2 R1 + abort "TouchZNative: probe did not release after backoff. Increase tp3_zBackoff." + +; --- Slow plunge --- +G91 +G1 H4 Z{-global.tp3_zSlowPlunge} F{global.tp3_fZSlow} +G90 +M400 + +M98 P"/macros/toolprobe_v3/_lib/Probe_IsTriggered.g" +if !global.tp3_probeTriggered + M98 P"/macros/toolprobe_v3/_lib/UseProbeAsEndstop.g" A2 R1 + abort "TouchZNative: slow plunge ran out without trigger. Increase tp3_zSlowPlunge." + +; userPosition gives tip Z (T-active) or carriage Z (T-1 — they're equal). The +; CalibrateActiveTool offset math relies on this being the tool-tip frame. +set global.tp3_lastZ = move.axes[2].userPosition + +; --- Restore Z endstop and lift --- +M98 P"/macros/toolprobe_v3/_lib/UseProbeAsEndstop.g" A2 R1 + +G91 +G1 Z{global.tp3_zBackoff + global.tp3_betweenTouchZLift} F{global.tp3_fZFast} +G90 + +M98 P"/macros/toolprobe_v3/_lib/Status.g" S{"Z touch = " ^ global.tp3_lastZ} diff --git a/RRF Implementation/_lib/UseProbeAsEndstop.g b/RRF Implementation/_lib/UseProbeAsEndstop.g new file mode 100644 index 0000000..5c15da9 --- /dev/null +++ b/RRF Implementation/_lib/UseProbeAsEndstop.g @@ -0,0 +1,39 @@ +; /macros/toolprobe_v3/_lib/UseProbeAsEndstop.g +; +; Assign or restore the endstop for one axis. Per-axis swap keeps the other +; axes on their real endstops during a scan, so an inadvertent G28 X (etc.) +; can't trigger off the tool probe. +; +; Params: +; A = 0 (X) | 1 (Y) | 2 (Z) +; R = 1 to RESTORE the default endstop for that axis (otherwise: assign probe) +; +; Defaults restored: +; X -> S1 P{tp3_endstopPinX} +; Y -> S1 P{tp3_endstopPinY} +; Z -> M574 Z0 (no physical Z endstop; matches your config.g) + +if !exists(param.A) + abort "UseProbeAsEndstop: requires A (0,1,2)" + +var axis = param.A +var restore = exists(param.R) && (param.R == 1) + +if var.restore + if var.axis == 0 + M574 X1 S1 P{global.tp3_endstopPinX} + elif var.axis == 1 + M574 Y1 S1 P{global.tp3_endstopPinY} + elif var.axis == 2 + M574 Z0 + else + abort "UseProbeAsEndstop: bad axis " ^ var.axis +else + if var.axis == 0 + M574 X1 S2 K{global.tp3_probeIndex} + elif var.axis == 1 + M574 Y1 S2 K{global.tp3_probeIndex} + elif var.axis == 2 + M574 Z1 S2 K{global.tp3_probeIndex} + else + abort "UseProbeAsEndstop: bad axis " ^ var.axis diff --git a/RRF Implementation/globals.g b/RRF Implementation/globals.g new file mode 100644 index 0000000..9f86d00 --- /dev/null +++ b/RRF Implementation/globals.g @@ -0,0 +1,178 @@ +; /macros/toolprobe_v3/globals.g +; +; toolprobe_v3 — best of both worlds: +; - Native G1 H4 probing (firmware-level, fast, accurate) -- from original toolprobe/ +; - Config / state / user-config separation -- from toolprobe_v2/ +; - Span + center-repeatability validation -- from toolprobe_v2/ +; - Dome geometry awareness -- from toolprobe_v2/ +; - Per-axis M574 swap, scoped at the top-level macro -- new +; - M118 status for DWC visibility -- new +; +; Naming: all globals live under the `tp3_` namespace so v3 coexists with v2 +; during the transition. Edit values via UserConfig.g, not here. + +; ============================================================================= +; PROBE SELECTION +; ============================================================================= + +; Tool probe index in your M558/G31 setup (your config has K3 = tool probe) +if !exists(global.tp3_probeIndex) + global tp3_probeIndex = 3 + +; Trigger band for digital probes (P8 reports 0 / 1000) +if !exists(global.tp3_probeTrigMin) + global tp3_probeTrigMin = 900 +if !exists(global.tp3_probeTrigMax) + global tp3_probeTrigMax = 1100 + + +; ============================================================================= +; ENDSTOP RESTORE PINS +; v3 owns its own pin globals so it does not depend on the older +; SetProbeConfig.g globals. Keep these in sync with config.g. +; ============================================================================= + +if !exists(global.tp3_endstopPinX) + global tp3_endstopPinX = "^io2" +if !exists(global.tp3_endstopPinY) + global tp3_endstopPinY = "^io1" + + +; ============================================================================= +; SEED VALUES (rough manual estimates, machine frame, T-1 active) +; After homing these should put the carriage within the probe footprint. +; Refined values are written to state.g at runtime. +; ============================================================================= + +if !exists(global.tp3_probeSeedX) + global tp3_probeSeedX = 263.8675 +if !exists(global.tp3_probeSeedY) + global tp3_probeSeedY = 309.9875 + +; Rough estimate of the probe-top Z (machine frame). +; Used only to place XY edge scans into the engagement band; true plane is +; measured by DiscoverProbeZ + TouchZNative. +if !exists(global.tp3_probeSeedZGuess) + global tp3_probeSeedZGuess = 4.140 + +; Vertical correction from contact plane to dome centerline. +; Used by tool-tip probing, not by LocateToolProbe itself. +if !exists(global.tp3_probeDomeZ) + global tp3_probeDomeZ = 0.5 + + +; ============================================================================= +; Z POLICY +; ============================================================================= + +; Global travel Z (machine frame) used between regions +if !exists(global.tp3_travelZ) + global tp3_travelZ = 15 + +; Local "above the probe" Z used as start point for Z touches +if !exists(global.tp3_workcellZ) + global tp3_workcellZ = 8 + +; Lift after each XY edge touch so cross moves don't drag the dome +if !exists(global.tp3_betweenTouchZLift) + global tp3_betweenTouchZLift = 0.5 + +; ===== CARRIAGE GEOMETRY — engagement depth for LocateToolProbe (T-1) ===== +; LocateToolProbe brackets the probe dome with the BARE CARRIAGE (T-1). After +; the first downward touch, the carriage drops THIS many mm further so the +; carriage's contact feature engages the dome's SIDE for the X/Y scans. +; +; - Has a Nudge / probe peg sticking 5+mm below the carriage: 1.0 - 1.5 +; - Has a small contact pin (1-2mm below carriage body): 0.3 - 0.7 +; - Just a flat carriage bottom (no dedicated probe feature): 0.0 - 0.1 +; +; If you see "ScanEdgeNative: probe already triggered at scan start" during +; LocateToolProbe, this value is too large for your contact feature — reduce +; it. If you see "probe did not trigger within 12mm scan", increase it. +if !exists(global.tp3_locateEngagementDepth) + global tp3_locateEngagementDepth = 0.5 + +; ===== TOOL TIP GEOMETRY — engagement depth for CalibrateActiveTool ===== +; After the tip-discovery touch, the tip drops THIS many mm further for the +; XY tip scans. Tool tips are usually small and fragile, so keep this shallow. +; Negative number = below the discovered touch point. +if !exists(global.tp3_toolNudgeZOffset) + global tp3_toolNudgeZOffset = -0.20 + + +; ============================================================================= +; XY GEOMETRY +; ============================================================================= + +; Half-window used to start an edge scan: probe is expected to be within +; tp3_edgeStart of the seed/refined center along each axis. +if !exists(global.tp3_edgeStart) + global tp3_edgeStart = 6.0 + +; Refine pass margin added beyond half-span before the second edge scan +if !exists(global.tp3_refineMargin) + global tp3_refineMargin = 0.5 + + +; ============================================================================= +; VALIDATION +; ============================================================================= + +; Acceptable measured span across the dome at engagement Z +if !exists(global.tp3_spanMin) + global tp3_spanMin = 1.0 +if !exists(global.tp3_spanMax) + global tp3_spanMax = 12.0 + +; Allowed mismatch between X and Y spans (symmetry sanity check) +if !exists(global.tp3_spanMatchTol) + global tp3_spanMatchTol = 1.0 + +; Allowed center movement between coarse and refine passes +if !exists(global.tp3_centerRepeatTol) + global tp3_centerRepeatTol = 0.05 + + +; ============================================================================= +; Z TOUCH PARAMETERS +; ============================================================================= + +if !exists(global.tp3_zFastPlunge) + global tp3_zFastPlunge = 10.0 +if !exists(global.tp3_zSlowPlunge) + global tp3_zSlowPlunge = 2.0 +if !exists(global.tp3_zBackoff) + global tp3_zBackoff = 1.0 + +; Plunge distance used by CalibrateActiveTool to discover where the actual +; tool tip touches the probe (handles existing G10 Z offset error). Must be +; larger than the gap from travelZ to the probe top in the worst-case tool +; offset error you expect. +if !exists(global.tp3_toolDiscoveryPlunge) + global tp3_toolDiscoveryPlunge = 20 + + +; ============================================================================= +; FEEDRATES (mm/min) +; ============================================================================= + +if !exists(global.tp3_fZFast) + global tp3_fZFast = 600 +if !exists(global.tp3_fZSlow) + global tp3_fZSlow = 50 +if !exists(global.tp3_fXYTravel) + global tp3_fXYTravel = 6000 +if !exists(global.tp3_fXYScan) + global tp3_fXYScan = 50 + + +; ============================================================================= +; DOCK BAND (Y range to avoid for cross-bed travel) +; ============================================================================= + +if !exists(global.tp3_dockYMin) + global tp3_dockYMin = 9999 ; disabled if min > max +if !exists(global.tp3_dockYMax) + global tp3_dockYMax = -9999 +if !exists(global.tp3_corridorY) + global tp3_corridorY = 150 ; safe Y outside the dock band diff --git a/RRF Implementation/state.g b/RRF Implementation/state.g new file mode 100644 index 0000000..9d22fbc --- /dev/null +++ b/RRF Implementation/state.g @@ -0,0 +1,35 @@ +; /macros/toolprobe_v3/state.g +; Runtime cache populated by LocateToolProbe.g and the leaf macros. +; Loads globals.g first so this file is safe to run standalone. + +M98 P"/macros/toolprobe_v3/globals.g" + +; --- Located probe (machine frame, T-1) --- +if !exists(global.tp3_located) + global tp3_located = false +if !exists(global.tp3_probeX) + global tp3_probeX = global.tp3_probeSeedX +if !exists(global.tp3_probeY) + global tp3_probeY = global.tp3_probeSeedY +if !exists(global.tp3_probeZPlane) + global tp3_probeZPlane = global.tp3_probeSeedZGuess + +; Workspace Z offset that was active when probeZPlane was captured. Used by +; CalibrateActiveTool to detect "autoz happened since LocateToolProbe" and +; demand a RefreshProbeZPlane.g run. Sentinel value -9999 means never set. +if !exists(global.tp3_probeZPlaneFrame) + global tp3_probeZPlaneFrame = -9999 + +; --- Last-touch scratch globals (written by leaf macros) --- +if !exists(global.tp3_lastEdge) + global tp3_lastEdge = 0 +if !exists(global.tp3_lastCenter) + global tp3_lastCenter = 0 +if !exists(global.tp3_lastSpan) + global tp3_lastSpan = 0 +if !exists(global.tp3_lastZ) + global tp3_lastZ = 0 +if !exists(global.tp3_discoveredEngageZ) + global tp3_discoveredEngageZ = 0 +if !exists(global.tp3_probeTriggered) + global tp3_probeTriggered = false