Skip to content

Commit 22bebc4

Browse files
committed
qtvcp -vera probe: first pass on getting tool diameter probing working.
One button was not implemented and so I looked up the code from verser probe in github nd added the code. should be able to probe th eheight and diameter of a tool. Currently doen;t start the spindle during probing
1 parent 36bc1b5 commit 22bebc4

5 files changed

Lines changed: 248 additions & 13 deletions

File tree

configs/sim/qtdragon/qtdragon_tool_probe/qtdragon_auto_tool_probe.ini

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,13 +163,17 @@ USE_PROBE = versaprobe
163163
# Abs (G53) coordinates remap tool change point
164164
X = 10
165165
Y = 10
166-
Z = -2
166+
Z = 8
167167

168168
# where in absolute machine units to probe the tool
169169
[VERSA_TOOLSETTER]
170170
X = 300
171171
Y = 300
172172
Z = -50
173+
# how migh to lift when moving to the tool setter
174+
Z_MAX_CLEAR = 9.999
175+
# tool setter diameter for diameter probing
176+
DIAMETER = 25
173177
# maximuim machine units to lower while probing
174178
MAXPROBE = -40
175179

lib/python/qtvcp/widgets/probe_routines.py

Lines changed: 193 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
class ProbeRoutines():
2121
def __init__(self):
2222
self.timeout = 30
23-
2423
##################
2524
# Helper Functions
2625
##################
@@ -126,6 +125,47 @@ def probe(self, name):
126125
return 'Probe {} failed: {}'.format(name, rtn)
127126
return 1
128127

128+
def goto_toolsetter(self):
129+
try:
130+
# basic sanity checks
131+
for test in('z_max_clear','ts_x','ts_y','ts_z','ts_max'):
132+
if self['data_{}'.format(test)] is None:
133+
return'Missing toolsetter setting: {}'.format(test)
134+
if self.data_tool_diameter is None:
135+
return 'No tool diameter found'
136+
137+
# raise to safe Z height
138+
# move to tool setter (XY then Z)
139+
# offset X by tool radius (from toolfile)
140+
# probe Z
141+
# raise z clear
142+
# move back X by tool radius
143+
144+
cmdList = []
145+
cmdList.append('F{}'.format(self.data_rapid_vel))
146+
cmdList.append('G53 G1 Z{}'.format(self.data_z_max_clear))
147+
cmdList.append('G53 G1 X{} Y{}'.format(self.data_ts_x, self.data_ts_y))
148+
cmdList.append('G53 G1 Z{}'.format(self.data_ts_z))
149+
cmdList.append('G91 ')
150+
cmdList.append('G1 X{}'.format(self.data_tool_diameter/2))
151+
cmdList.append('G38.2 Z{} F{}'.format(self.data_ts_max,self.data_search_vel))
152+
cmdList.append('G1 Z{} F{}'.format(self.data_latch_return_dist, self.data_rapid_vel))
153+
cmdList.append('F{} G4 P0.5'.format(self.data_probe_vel))
154+
cmdList.append('G38.2 Z-{}'.format(self.data_latch_return_dist*2))
155+
cmdList.append('G1 Z{} F{}'.format(self.data_z_clearance, self.data_rapid_vel))
156+
cmdList.append('G1 X-{}'.format(self.data_tool_diameter/2))
157+
cmdList.append('G90')
158+
159+
# call each command - if fail report the error and gcode command
160+
for s in cmdList:
161+
rtn = self.CALL_MDI_WAIT(s, self.timeout)
162+
if rtn != 1:
163+
return 'failed: {} cmd: {}'.format(rtn, s)
164+
# report success
165+
return 1
166+
except Exception as e:
167+
return e
168+
129169
def CALL_MDI_WAIT(self, code, timeout = 5):
130170
LOG.debug('MDI_WAIT_COMMAND= {}, maxt = {}'.format(code, timeout))
131171
for l in code.split("\n"):
@@ -1483,7 +1523,7 @@ def probe_valley_y(self):
14831523
def probe_cal_round_pocket(self):
14841524
if self.data_cal_diameter_hint <= 0 :
14851525
return 'Calibration diameter hint must be larger then 0'
1486-
if self.data_probe_diameter >= self.data_cal_diameter_hint:
1526+
if self.data_probe_diam >= self.data_cal_diameter_hint:
14871527
return 'Probe diameter too large for Calibration diameter hint'
14881528

14891529
self.data_side_edge_length = self.data_cal_diameter / 2
@@ -1631,3 +1671,154 @@ def probe_angle_right(self):
16311671
self.status_a = math.degrees(math.atan2(self.status_delta, self.data_side_edge_length))
16321672
self.rotate_coord_system(self.status_a)
16331673
return error
1674+
1675+
# TOOL setter Diameter/height
1676+
# returns 1 for success or a string error message for failure
1677+
def probe_tool_z_d(self):
1678+
try:
1679+
# move XY to Tool Setter point
1680+
# Start goto ts (probes Z height too)
1681+
rtn = self.goto_toolsetter()
1682+
if rtn != 1:
1683+
return 'failed: {}'.format(rtn)
1684+
# move X - edge_length- xy_clearance
1685+
s="""G91
1686+
G1 F%s X-%f
1687+
G90""" % (self.data_rapid_vel, 0.5 * self.data_ts_diam + self.data_xy_clearance)
1688+
rtn = self.CALL_MDI_WAIT(s, self.timeout)
1689+
if rtn != 1:
1690+
return 'failed: {}'.format(rtn)
1691+
rtn = self.z_clearance_down()
1692+
if rtn != 1:
1693+
return 'failed: {}'.format(rtn)
1694+
1695+
# Start xplus
1696+
rtn = self.probe('xplus')
1697+
if rtn != 1:
1698+
return 'failed: {}'.format(rtn)
1699+
1700+
# show X result
1701+
a = STATUS.get_probed_position_with_offsets()
1702+
xpres=float(a[0])+0.5*self.data_probe_diam
1703+
1704+
# move Z to start point up
1705+
rtn = self.z_clearance_up()
1706+
if rtn != 1:
1707+
return 'failed: {}'.format(rtn)
1708+
1709+
# move to finded point X
1710+
s = "G1 F%s X%f" % (self.data_rapid_vel, xpres)
1711+
rtn = self.CALL_MDI_WAIT(s, self.timeout)
1712+
if rtn != 1:
1713+
return 'failed: {}'.format(rtn)
1714+
1715+
# move X + data_ts_diam + xy_clearance
1716+
aa=self.data_ts_diam+self.data_xy_clearance
1717+
s="""G91
1718+
G1 X%f
1719+
G90""" % (aa)
1720+
rtn = self.CALL_MDI_WAIT(s, self.timeout)
1721+
if rtn != 1:
1722+
return 'failed: {}'.format(rtn)
1723+
1724+
rtn = self.z_clearance_down()
1725+
if rtn != 1:
1726+
return 'failed: {}'.format(rtn)
1727+
1728+
# Start xminus
1729+
rtn = self.probe('xminus')
1730+
if rtn != 1:
1731+
return 'failed: {}'.format(rtn)
1732+
1733+
# show X result
1734+
a = STATUS.get_probed_position_with_offsets()
1735+
xmres=float(a[0])-0.5*self.data_probe_diam
1736+
self.length_x()
1737+
xcres=0.5*(xpres+xmres)
1738+
self.status_xc = xcres
1739+
1740+
# move Z to start point up
1741+
rtn = self.z_clearance_up()
1742+
if rtn != 1:
1743+
return 'failed: {}'.format(rtn)
1744+
1745+
# go to the new center of X
1746+
s = "G1 F%s X%f" % (self.data_rapid_vel, xcres)
1747+
rtn = self.CALL_MDI_WAIT(s, self.timeout)
1748+
if rtn != 1:
1749+
return 'failed: {}'.format(rtn)
1750+
1751+
# move Y - data_ts_diam/2 - xy_clearance
1752+
a=0.5*self.data_ts_diam+self.data_xy_clearance
1753+
s="""G91
1754+
G1 Y-%f
1755+
G90""" % a
1756+
rtn = self.CALL_MDI_WAIT(s, self.timeout)
1757+
if rtn != 1:
1758+
return 'failed: {}'.format(rtn)
1759+
1760+
rtn = self.z_clearance_down()
1761+
if rtn != 1:
1762+
return 'failed: {}'.format(rtn)
1763+
1764+
# Start yplus
1765+
rtn = self.probe('yplus')
1766+
if rtn != 1:
1767+
return 'failed: {}'.format(rtn)
1768+
1769+
# show Y result
1770+
a = STATUS.get_probed_position_with_offsets()
1771+
ypres=float(a[1])+0.5*self.data_probe_diam
1772+
# move Z to start point up
1773+
if self.z_clearance_up() == -1:
1774+
return
1775+
1776+
# move to found point Y
1777+
s = "G1 Y%f" % ypres
1778+
rtn = self.CALL_MDI_WAIT(s, self.timeout)
1779+
if rtn != 1:
1780+
return 'failed: {}'.format(rtn)
1781+
1782+
# move Y + data_ts_diam + xy_clearance
1783+
aa=self.data_ts_diam+self.data_xy_clearance
1784+
s="""G91
1785+
G1 Y%f
1786+
G90""" % (aa)
1787+
rtn = self.CALL_MDI_WAIT(s, self.timeout)
1788+
if rtn != 1:
1789+
return 'failed: {}'.format(rtn)
1790+
rtn = self.z_clearance_down()
1791+
if rtn != 1:
1792+
return 'failed: {}'.format(rtn)
1793+
1794+
# Start yminus
1795+
rtn = self.probe('yminus')
1796+
if rtn != 1:
1797+
return 'failed: {}'.format(rtn)
1798+
# show Y result
1799+
a = STATUS.get_probed_position_with_offsets()
1800+
ymres=float(a[1])-0.5*self.data_probe_diam
1801+
self.length_y()
1802+
1803+
# find, show and move to finded point
1804+
ycres=0.5*(ypres+ymres)
1805+
self.status_yc = ycres
1806+
diam=self.data_probe_diam + (ymres-ypres-self.data_ts_diam)
1807+
self.status_d = diam
1808+
1809+
# move Z to start point up
1810+
rtn = self.z_clearance_up()
1811+
if rtn != 1:
1812+
return 'failed: {}'.format(rtn)
1813+
tmpz=STATUS.stat.position[2] - self.data_z_clearance
1814+
self.status_z=tmpz
1815+
self.add_history('Tool diameter',"XcYcZD",0,xcres,0,0,0,ycres,0,0,tmpz,diam,0)
1816+
# move to finded point
1817+
s = "G1 Y%f" % ycres
1818+
rtn = self.CALL_MDI_WAIT(s, self.timeout)
1819+
if rtn != 1:
1820+
return 'failed: {}'.format(rtn)
1821+
# success
1822+
return 1
1823+
except Exception as e:
1824+
return e

lib/python/qtvcp/widgets/probe_subprog.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,15 @@ def __init__(self):
6363
'cal_x_width',
6464
'cal_y_width',
6565
'cal_diameter',
66-
'calibration_offset']
66+
'calibration_offset',
67+
'ts_diam',
68+
'z_max_clear',
69+
'ts_x',
70+
'ts_y',
71+
'ts_z',
72+
'ts_max',
73+
'tool_diameter']
74+
6775
# data structure to hold parameters
6876
# common
6977
self.data_probe_diam = 1.0
@@ -84,6 +92,13 @@ def __init__(self):
8492
self.data_adj_y = 0.0
8593
self.data_adj_z = 0.0
8694
self.data_adj_angle = 0.0
95+
self.data_ts_diam = 1.0
96+
self.data_z_max_clear = None
97+
self.data_ts_x= None
98+
self.data_ts_y= None
99+
self.data_ts_z= None
100+
self.data_ts_max = None
101+
self.data_tool_diameter = None
87102
# BasicProbe exclusive
88103
self.data_x_hint_bp = 0.0
89104
self.data_y_hint_bp = 0.0

lib/python/qtvcp/widgets/versa_probe.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ class VersaProbe(QtWidgets.QWidget, _HalWidgetBase):
4949
def __init__(self, parent=None):
5050
super(VersaProbe, self).__init__(parent)
5151
self.proc = None
52+
self.tool_diameter = None
53+
STATUS.connect('tool-info-changed', lambda w, data: self._tool_info(data))
5254
if INFO.MACHINE_IS_METRIC:
5355
self.valid = QtGui.QRegExpValidator(QtCore.QRegExp('^((\d{1,4}(\.\d{1,3})?)|(\.\d{1,3}))$'))
5456
else:
@@ -113,6 +115,14 @@ def eventFilter(self, obj, event):
113115
self.popEntry(obj)
114116
return super(VersaProbe, self).eventFilter(obj, event)
115117

118+
119+
def _tool_info(self, data):
120+
if data.id != -1:
121+
self.tool_diameter = data.diameter
122+
print(data)
123+
return
124+
self.tool_diameter = None
125+
116126
def _hal_init(self):
117127

118128
def homed_on_test():
@@ -177,6 +187,13 @@ def homed_on_test():
177187
self.input_adj_angle.setText(str(self.PREFS_.getpref( "ps_offs_angle", 0.0, float, 'VERSA_PROBE_OPTIONS')) )
178188
self.input_rapid_vel.setText(str(self.PREFS_.getpref( "ps_probe_rapid_vel", 60.0, float, 'VERSA_PROBE_OPTIONS')) )
179189

190+
self.z_max_clear = INFO.get_safe_float("VERSA_TOOLSETTER", "Z_MAX_CLEAR")
191+
self.ts_x = INFO.get_safe_float('VERSA_TOOLSETTER','X')
192+
self.ts_y = INFO.get_safe_float('VERSA_TOOLSETTER','Y')
193+
self.ts_z = INFO.get_safe_float('VERSA_TOOLSETTER','Z')
194+
self.ts_max = INFO.get_safe_float('VERSA_TOOLSETTER','MAXPROBE')
195+
self.ts_diam = INFO.get_safe_float('VERSA_TOOLSETTER','DIAMETER')
196+
180197
# make pins available for tool measure remaps
181198
oldname = self.HAL_GCOMP_.comp.getprefix()
182199
self.HAL_GCOMP_.comp.setprefix('qtversaprobe')
@@ -397,6 +414,11 @@ def get_parms(self):
397414
for key in ['allow_auto_zero', 'allow_auto_skew']:
398415
val = '1' if self[key].isChecked() else '0'
399416
self.send_dict.update( {key: val} )
417+
# come from INI
418+
for key in ['ts_diam','z_max_clear','ts_x','ts_y','ts_z','ts_max','tool_diameter']:
419+
val = str(self[key])
420+
if val == 'NONE': val = None
421+
self.send_dict.update( {key: val} )
400422

401423
def check_probe(self):
402424
try:

share/qtvcp/widgets_ui/versa_probe.ui

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2767,7 +2767,7 @@
27672767
<item row="4" column="2">
27682768
<widget class="PushButton" name="pbtn_measure_diam">
27692769
<property name="enabled">
2770-
<bool>false</bool>
2770+
<bool>true</bool>
27712771
</property>
27722772
<property name="sizePolicy">
27732773
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@@ -2788,7 +2788,7 @@
27882788
</size>
27892789
</property>
27902790
<property name="toolTip">
2791-
<string>This button not implemented</string>
2791+
<string>Probe height and diameter of the current tool</string>
27922792
</property>
27932793
<property name="text">
27942794
<string/>
@@ -2813,8 +2813,11 @@
28132813
<bool>false</bool>
28142814
</property>
28152815
<property name="probe" stdset="0">
2816-
<string>probe_help</string>
2816+
<string>probe_tool_z_d</string>
28172817
</property>
2818+
<attribute name="buttonGroup">
2819+
<string notr="true">length_buttonGroup</string>
2820+
</attribute>
28182821
</widget>
28192822
</item>
28202823
<item row="2" column="2">
@@ -5311,8 +5314,8 @@ ZERO</string>
53115314
<slot>input_next()</slot>
53125315
<hints>
53135316
<hint type="sourcelabel">
5314-
<x>101</x>
5315-
<y>399</y>
5317+
<x>112</x>
5318+
<y>386</y>
53165319
</hint>
53175320
<hint type="destinationlabel">
53185321
<x>779</x>
@@ -5386,22 +5389,22 @@ ZERO</string>
53865389
<slot>input_next()</slot>
53875390
</slots>
53885391
<buttongroups>
5389-
<buttongroup name="inside_buttonGroup">
5392+
<buttongroup name="outside_buttonGroup">
53905393
<property name="exclusive">
53915394
<bool>false</bool>
53925395
</property>
53935396
</buttongroup>
5394-
<buttongroup name="skew_buttonGroup">
5397+
<buttongroup name="length_buttonGroup">
53955398
<property name="exclusive">
53965399
<bool>false</bool>
53975400
</property>
53985401
</buttongroup>
5399-
<buttongroup name="outside_buttonGroup">
5402+
<buttongroup name="inside_buttonGroup">
54005403
<property name="exclusive">
54015404
<bool>false</bool>
54025405
</property>
54035406
</buttongroup>
5404-
<buttongroup name="length_buttonGroup">
5407+
<buttongroup name="skew_buttonGroup">
54055408
<property name="exclusive">
54065409
<bool>false</bool>
54075410
</property>

0 commit comments

Comments
 (0)