Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 146 additions & 0 deletions RRF Implementation/CalibrateActiveTool.g
Original file line number Diff line number Diff line change
@@ -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}
45 changes: 45 additions & 0 deletions RRF Implementation/CalibrateToolRange.g
Original file line number Diff line number Diff line change
@@ -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"
118 changes: 118 additions & 0 deletions RRF Implementation/LocateToolProbe.g
Original file line number Diff line number Diff line change
@@ -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}
55 changes: 55 additions & 0 deletions RRF Implementation/RefreshProbeZPlane.g
Original file line number Diff line number Diff line change
@@ -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 ^ ")"}
Loading