(author: Chris P)
(version: 0.1)
(date: 04/27/19)

(Probe Boss in X and Y Axes, find center, Diam and z 0 position)
(Start probe position is over center of stock in X and Y axis)
(within max z distance, ensure all settings have been)
(set properly according to help diagrams)

o<probe_round_boss> sub

  (uses NGCGUI style arg spec)
  (number after "=" in comment is default value)
  #<probe_tool_number> = #1    (=99)
  #<max_z_distance> = #2       (=0.5000)
  #<max_xy_distance> = #3      (=0.5000)
  #<xy_clearance> = #4         (=0.1000)
  #<z_clearance> = #5          (=0.1000)
  #<step_off_width> = #6       (=0.5000)
  #<extra_probe_depth> = #7    (=0.0000)
  #<probe_slow_fr> = #8        (=0.0)
  #<probe_fast_fr> = #9        (=10.0)
  #<calibration_offset> = #10  (=0.0000)
  #<x_hint> = #11              (=1.0000)
  #<y_hint> = #12              (=1.0000)
  #<diameter_hint> = #13       (=1.0000)
  #<edge_width> = #14          (=0.5000)
  #<probe_mode> = #15          (=0)

  (Cancel G92 offsets)
  G92.1

  #<workspace_x> = #[5201 + [20 * #5220]]
  #<workspace_y> = #[5202 + [20 * #5220]]
  #<workspace_z> = #[5203 + [20 * #5220]]

  (Probe Tool Safety Check)
  o<110> if [#5400 NE #<probe_tool_number>]
  (MSG, Specified probe tool #<probe_tool_number> not in spindle, aborting)
   o<probe_round_boss> return
  o<110> endif

  (Probe Diameter)
  #<probe_diameter> = #5410

  (Probe Radius)
  #<probe_radius> = [#<probe_diameter> / 2]

  (Probe Centerline Offset)
  #<probe_center_offset> = [#<probe_radius> - #<calibration_offset>]

  (remove probe tip diam and cal offset from probed width calculations)
  #<probe_diameter_offset> = [#<probe_diameter> - [#<calibration_offset> * 2]]

  #<z_probe_stack> = [#<z_clearance> + #<probe_diameter> + #<extra_probe_depth>]

  (Probe X Positioning Move, X hint/2 + Step Off Width)
  G91
  G0 X-[#<diameter_hint>/2 + #<step_off_width>]

  (Probe X Positioning Move, to Probing Depth)
  F[#<probe_fast_fr>]
  G1 Z-[#<z_probe_stack>]

  (Call sub "probe_x_plus" to Probe x+ side of Workpiece)
  o<probe_x_plus> call [#1][#3][#4][#8][#9][#10]

  #<x_plus_probed> = #5061

  (first side Probe Completion Move to Z Clearance Plane)
  G91
  G0 Z[#<z_probe_stack>]

  (Positioning move in X, X Hint + Step Off Width at Rapid Speed)
  G91
  G0 X[#<diameter_hint> + #<step_off_width>*2 ]

  (Probe X Positioning Move, to Probing Depth)
  F[#<probe_fast_fr>]
  G1 Z-[#<z_probe_stack>]

  (Call sub "probe_x_minus" to Probe x- side of Workpiece)
  o<probe_x_minus> call [#1][#3][#4][#8][#9][#10]

  #<x_minus_probed> = #5061

  (probed center calculation)
  #<x_center_probed> = [[#<x_minus_probed> + #<x_plus_probed>] / 2]

  M68 E10 Q[#<x_center_probed>]

  G91
  G0 Z[#<z_probe_stack>]
  G90
  G0 X[#<x_center_probed>]

  (Probe Y Positioning Move, Y hint/2 + Step Off Width)
  G91
  G0 Y-[#<diameter_hint>/2 + #<step_off_width>]

  (Probe Y Positioning Move, to Probing Depth)
  F[#<probe_fast_fr>]
  G1 Z-[#<z_probe_stack>]

  (Call sub "probe_y_plus" to Probe y+ side of Workpiece)
  o<probe_y_plus> call [#1][#3][#4][#8][#9][#10]

  #<y_plus_probed> = #5062

  (first side Probe Completion Move to Z Clearance Plane)
  G91
  G0 Z[#<z_probe_stack>]

  (Positioning move in Y, Y Hint + Step Off Width at Rapid Speed)
  G91
  G0 Y[#<diameter_hint> + #<step_off_width>*2]

  (Probe Y Positioning Move, to Probing Depth)
  F[#<probe_fast_fr>]
  G0 Z-[#<z_probe_stack>]

  (Call sub "probe_y_minus" to Probe y- side of Workpiece)
  o<probe_y_minus> call [#1][#3][#4][#8][#9][#10]

  #<y_minus_probed> = #5062

  (probed center calculation)
  #<y_center_probed> = [[#<y_minus_probed> + #<y_plus_probed>] / 2]

  M68 E11 Q[#<y_center_probed>]

  (Move to z clearance plane)
  G91
  G0 Z[#<z_probe_stack>]

  (Move to Y Center)
  G90
  G0 Y[#<y_center_probed>]

  (calculate X Width Probed)
  o<120> if [#<x_minus_probed> GT #<x_plus_probed>]
    #<x_raw_width> = [#<x_minus_probed> - #<x_plus_probed>]
  o<120> else
    #<x_raw_width> = [#<x_plus_probed> - #<x_minus_probed>]
  o<120> endif

  (Completed probed width calculations)
  #<x_probed_width> = [#<x_raw_width> - #<probe_diameter_offset>]

  M68 E0 Q[#<x_probed_width>]

  G90
  G0 X[#<x_center_probed>]

  (probed center calculation)
  #<y_center_probed> = [[#<y_minus_probed> + #<y_plus_probed>] / 2]

  (calculate Y Width Probed)
  o<130> if [#<y_minus_probed> GT #<y_plus_probed>]
    #<y_raw_width> = [#<y_minus_probed> - #<y_plus_probed>]
  o<130> else
    #<y_raw_width> = [#<y_plus_probed> - #<y_minus_probed>]
  o<130> endif

  (Completed probed width calculations)
  #<y_probed_width> = [#<y_raw_width> - #<probe_diameter_offset>]

  M68 E1 Q[#<y_probed_width>]

  #<averaged_diam> = [[#<x_probed_width> + #<y_probed_width>] / 2]

  M68 E2 Q[#<averaged_diam>]

  #<x_zero> = [#<x_center_probed> + #<workspace_x>]

  #<y_zero> = [#<y_center_probed> + #<workspace_y>]

  (probe mode rules for WCO or probe position measuring only)
  o<140> if [#<probe_mode> EQ 0]
    (Record XY Zero in selected WCO)
    G10 L2 P#5220 X[#<x_zero>] Y[#<y_zero>]
    o<probe_round_boss> return
  o<140> endif

o<probe_round_boss> endsub

M2 (end program)

