Skip to content

Commit e7cd165

Browse files
committed
PNCconf automatic G43 for Gmoccapy
1 parent 454df73 commit e7cd165

7 files changed

Lines changed: 364 additions & 0 deletions

File tree

src/emc/usr_intf/pncconf/build_INI.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,17 @@ def write_inifile(self, base):
174174
p =.001
175175
print ("RS274NGC_STARTUP_CODE = G{} G40 G90 G94 G97 G64 P{}".format(unit,p), file=file)
176176

177+
if self.d.frontend == _PD._GMOCCAPY:
178+
print("SUBROUTINE_PATH = ./macros", file=file)
179+
print("REMAP=M6 modalgroup=6 prolog=change_prolog ngc=change_g43 epilog=change_epilog", file=file)
180+
print("REMAP=M61 modalgroup=6 prolog=settool_prolog ngc=settool_g43 epilog=settool_epilog", file=file)
181+
print(file=file)
182+
print("# the Python plugins serves interpreter and task", file=file)
183+
print("[PYTHON]", file=file)
184+
print("PATH_PREPEND = ./python", file=file)
185+
print("TOPLEVEL = ./python/toplevel.py", file=file)
186+
print("LOG_LEVEL = 0", file=file)
187+
177188
#base_period = self.d.ideal_period()
178189

179190
print(file=file)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
o<change_g43> sub
2+
;(debug, in change tool_in_spindle=#<tool_in_spindle> current_pocket=#<current_pocket>)
3+
;(debug, selected_tool=#<selected_tool> selected_pocket=#<selected_pocket>)
4+
5+
; we must execute this only in the milltask interpreter
6+
; or preview will break, so test for '#<_task>' which is 1 for
7+
; the milltask interpreter and 0 in the UI's
8+
O100 if [#<_task> EQ 0]
9+
(debug, Task ist Null)
10+
O100 return [999]
11+
O100 endif
12+
13+
; using the code being remapped here means 'use builtin behaviour'
14+
M6
15+
16+
; set tool offset
17+
G43
18+
19+
; signal success be returning a value > 0:
20+
o<change_g43> endsub [1]
21+
M2
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
o<settool_g43> sub
2+
;(debug, tool=#<tool> pocket=#<pocket>)
3+
4+
; we must execute this only in the milltask interpreter
5+
; or preview will break, so test for '#<_task>' which is 1 for
6+
; the milltask interpreter and 0 in the UI's
7+
O100 if [#<_task> EQ 0]
8+
(debug, Task ist Null)
9+
O100 return [999]
10+
O100 endif
11+
12+
; using the code being remapped here means 'use builtin behaviour'
13+
M61 q#<tool>
14+
15+
; set tool offset
16+
G43
17+
18+
; signal success be returning a value > 0:
19+
o<settool_g43> endsub [1]
20+
M2
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# This is a component of LinuxCNC
2+
# Copyright 2011, 2012, 2013, 2014 Dewey Garrett <dgarrett@panix.com>,
3+
# Michael Haberler <git@mah.priv.at>, Norbert Schechner <nieson@web.de>
4+
#
5+
# This program is free software; you can redistribute it and/or modify
6+
# it under the terms of the GNU General Public License as published by
7+
# the Free Software Foundation; either version 2 of the License, or
8+
# (at your option) any later version.
9+
#
10+
# This program is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
# GNU General Public License for more details.
14+
#
15+
# You should have received a copy of the GNU General Public License
16+
# along with this program; if not, write to the Free Software
17+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18+
#
19+
from stdglue import *
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
#NOTE:
2+
# The legacy names *selected_pocket* and *current_pocket* actually reference
3+
# a sequential tooldata index for tool items loaded from a tool
4+
# table ([EMCIO]TOOL_TABLE) or via a tooldata database ([EMCIO]DB_PROGRAM)
5+
6+
# This is a component of LinuxCNC
7+
# Copyright 2014 Norbert Schechner <nieson@web.de>
8+
#
9+
# This program is free software; you can redistribute it and/or modify
10+
# it under the terms of the GNU General Public License as published by
11+
# the Free Software Foundation; either version 2 of the License, or
12+
# (at your option) any later version.
13+
#
14+
# This program is distributed in the hope that it will be useful,
15+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
# GNU General Public License for more details.
18+
#
19+
# You should have received a copy of the GNU General Public License
20+
# along with this program; if not, write to the Free Software
21+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22+
#
23+
# gmoccapy - Remap of M6 for auto tool measurement
24+
25+
import os
26+
import sys
27+
import emccanon
28+
from interpreter import *
29+
from gscreen import preferences
30+
throw_exceptions = 1
31+
32+
debug = False
33+
if debug:
34+
pydevdir = '/home/emcmesa/Aptana_Studio_3/plugins/org.python.pydev_2.7.0.2013032300/pysrc'
35+
36+
# the 'emctask' module is present only in the milltask instance, otherwise both the UI and
37+
# milltask would try to connect to the debug server.
38+
39+
if os.path.isdir( pydevdir ) and 'emctask' in sys.builtin_module_names:
40+
sys.path.append( pydevdir )
41+
sys.path.insert( 0, pydevdir )
42+
try:
43+
import pydevd
44+
emccanon.MESSAGE( "pydevd imported, connecting to Eclipse debug server..." )
45+
pydevd.settrace()
46+
except:
47+
emccanon.MESSAGE( "no pydevd module found" )
48+
pass
49+
50+
51+
# REMAP=M61 modalgroup=6 prolog=settool_prolog ngc=settool epilog=settool_epilog
52+
# exposed parameters: #<tool> #<pocket>
53+
54+
def settool_prolog(self,**words):
55+
try:
56+
c = self.blocks[self.remap_level]
57+
if not c.q_flag:
58+
self.set_errormsg("M61 requires a Q parameter")
59+
return INTERP_ERROR
60+
tool = int(c.q_number)
61+
if tool < -TOLERANCE_EQUAL: # 'less than 0 within interp's precision'
62+
self.set_errormsg("M61: Q value < 0")
63+
return INTERP_ERROR
64+
(status,pocket) = self.find_tool_pocket(tool)
65+
if status != INTERP_OK:
66+
self.set_errormsg("M61 failed: requested tool %d not in table" % (tool))
67+
return status
68+
self.params["tool"] = tool
69+
self.params["pocket"] = pocket
70+
return INTERP_OK
71+
except Exception as e:
72+
self.set_errormsg("M61/settool_prolog: %s)" % (e))
73+
return INTERP_ERROR
74+
75+
def settool_epilog(self,**words):
76+
try:
77+
if not self.value_returned:
78+
r = self.blocks[self.remap_level].executing_remap
79+
self.set_errormsg("the %s remap procedure %s did not return a value"
80+
% (r.name,r.remap_ngc if r.remap_ngc else r.remap_py))
81+
return INTERP_ERROR
82+
83+
if self.blocks[self.remap_level].builtin_used:
84+
#print "---------- M61 builtin recursion, nothing to do"
85+
return INTERP_OK
86+
else:
87+
if self.return_value > 0.0:
88+
self.current_tool = int(self.params["tool"])
89+
self.current_pocket = int(self.params["pocket"])
90+
emccanon.CHANGE_TOOL_NUMBER(self.current_pocket)
91+
# cause a sync()
92+
self.tool_change_flag = True
93+
self.set_tool_parameters()
94+
else:
95+
self.set_errormsg("M61 aborted (return code %.1f)" % (self.return_value))
96+
return INTERP_ERROR
97+
except Exception as e:
98+
self.set_errormsg("M61/settool_epilog: %s)" % (e))
99+
return INTERP_ERROR
100+
101+
102+
# REMAP=M6 modalgroup=6 prolog=change_prolog ngc=change epilog=change_epilog
103+
# exposed parameters:
104+
# #<tool_in_spindle>
105+
# #<selected_tool>
106+
# #<current_pocket>
107+
# #<selected_pocket>
108+
109+
def change_prolog(self, **words):
110+
try:
111+
# this is relevant only when using iocontrol-v2.
112+
if self.params[5600] > 0.0:
113+
if self.params[5601] < 0.0:
114+
self.set_errormsg("Toolchanger hard fault %d" % (int(self.params[5601])))
115+
return INTERP_ERROR
116+
print("change_prolog: Toolchanger soft fault %d" % int(self.params[5601]))
117+
118+
if self.selected_pocket < 0:
119+
self.set_errormsg("M6: no tool prepared")
120+
return INTERP_ERROR
121+
122+
if self.cutter_comp_side:
123+
self.set_errormsg("Cannot change tools with cutter radius compensation on")
124+
return INTERP_ERROR
125+
self.params["tool_in_spindle"] = self.current_tool
126+
self.params["selected_tool"] = self.selected_tool
127+
self.params["current_pocket"] = self.current_pocket # this is probably nonsense
128+
self.params["selected_pocket"] = self.selected_pocket
129+
return INTERP_OK
130+
131+
except Exception as e:
132+
self.set_errormsg("M6/change_prolog: %s" % (e))
133+
return INTERP_ERROR
134+
135+
def change_epilog(self, **words):
136+
try:
137+
if not self.value_returned:
138+
r = self.blocks[self.remap_level].executing_remap
139+
self.set_errormsg("the %s remap procedure %s did not return a value"
140+
% (r.name,r.remap_ngc if r.remap_ngc else r.remap_py))
141+
return INTERP_ERROR
142+
143+
if self.return_value > 0.0:
144+
if self.return_value == 3:
145+
message = "No tool measurement ! Please take care of the entry in the tool table"
146+
emccanon.MESSAGE(message)
147+
return INTERP_OK
148+
else:
149+
if self.return_value == -1:
150+
message = "Searchvel <= 0, not permitted!, Please correct INI Settings."
151+
elif self.return_value == -2:
152+
message = "Probevel <= 0, not permitted!, Please correct INI Settings."
153+
elif self.return_value == -3:
154+
message = "Probe contact failure !!"
155+
else:
156+
message = "M6 aborted (return code %.1f)" % (self.return_value)
157+
self.set_errormsg(message)
158+
return INTERP_ERROR
159+
160+
except Exception as e:
161+
self.set_errormsg("M6/change_epilog: %s" % (e))
162+
return INTERP_ERROR
163+
164+
165+
_uvw = ("u","v","w","a","b","c")
166+
_xyz = ("x","y","z","a","b","c")
167+
# given a plane, return sticky words, incompatible axis words and plane name
168+
# sticky[0] is also the movement axis
169+
_compat = {
170+
emccanon.CANON_PLANE_XY : (("z","r"),_uvw,"XY"),
171+
emccanon.CANON_PLANE_YZ : (("x","r"),_uvw,"YZ"),
172+
emccanon.CANON_PLANE_XZ : (("y","r"),_uvw,"XZ"),
173+
emccanon.CANON_PLANE_UV : (("w","r"),_xyz,"UV"),
174+
emccanon.CANON_PLANE_VW : (("u","r"),_xyz,"VW"),
175+
emccanon.CANON_PLANE_UW : (("v","r"),_xyz,"UW")}
176+
177+
# extract and pass parameters from current block, merged with extra parameters on a continuation line
178+
# keep tjose parameters across invocations
179+
# export the parameters into the oword procedure
180+
def cycle_prolog(self,**words):
181+
# self.sticky_params is assumed to have been initialized by the
182+
# init_stgdlue() method below
183+
global _compat
184+
try:
185+
# determine whether this is the first or a subsequent call
186+
c = self.blocks[self.remap_level]
187+
r = c.executing_remap
188+
if c.g_modes[1] == r.motion_code:
189+
# first call - clear the sticky dict
190+
self.sticky_params[r.name] = dict()
191+
192+
self.params["motion_code"] = c.g_modes[1]
193+
194+
(sw,incompat,plane_name) =_compat[self.plane]
195+
for (word,value) in words.items():
196+
# inject current parameters
197+
self.params[word] = value
198+
# record sticky words
199+
if word in sw:
200+
if self.debugmask & 0x00080000: print("%s: record sticky %s = %.4f" % (r.name,word,value))
201+
self.sticky_params[r.name][word] = value
202+
if word in incompat:
203+
return "%s: Cannot put a %s in a canned cycle in the %s plane" % (r.name, word.upper(), plane_name)
204+
205+
# inject sticky parameters which were not in words:
206+
for (key,value) in self.sticky_params[r.name].items():
207+
if not key in words:
208+
if self.debugmask & 0x00080000: print("%s: inject sticky %s = %.4f" % (r.name,key,value))
209+
self.params[key] = value
210+
211+
if not "r" in self.sticky_params[r.name]:
212+
return "%s: cycle requires R word" % (r.name)
213+
else:
214+
if self.sticky_params[r.name] <= 0.0:
215+
return "%s: R word must be > 0 if used (%.4f)" % (r.name, words["r"])
216+
217+
if "l" in words:
218+
# checked in interpreter during block parsing
219+
# if l <= 0 or l not near an int
220+
self.params["l"] = words["l"]
221+
222+
if "p" in words:
223+
p = words["p"]
224+
if p < 0.0:
225+
return "%s: P word must be >= 0 if used (%.4f)" % (r.name, p)
226+
self.params["p"] = p
227+
228+
if self.feed_rate == 0.0:
229+
return "%s: feed rate must be > 0" % (r.name)
230+
if self.feed_mode == INVERSE_TIME:
231+
return "%s: Cannot use inverse time feed with canned cycles" % (r.name)
232+
if self.cutter_comp_side:
233+
return "%s: Cannot use canned cycles with cutter compensation on" % (r.name)
234+
return INTERP_OK
235+
236+
except Exception as e:
237+
raise
238+
return "cycle_prolog failed: %s" % (e)
239+
240+
# make sure the next line has the same motion code, unless overridden by a
241+
# new G-code
242+
def cycle_epilog(self,**words):
243+
try:
244+
c = self.blocks[self.remap_level]
245+
self.motion_mode = c.executing_remap.motion_code # retain the current motion mode
246+
return INTERP_OK
247+
except Exception as e:
248+
return "cycle_epilog failed: %s" % (e)
249+
250+
# this should be called from TOPLEVEL __init__()
251+
def init_stdglue(self):
252+
self.sticky_params = dict()
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# This is a component of LinuxCNC
2+
# Copyright 2011, 2013, 2014 Dewey Garrett <dgarrett@panix.com>,
3+
# Michael Haberler <git@mah.priv.at>, Norbert Schechner <nieson@web.de>
4+
#
5+
# This program is free software; you can redistribute it and/or modify
6+
# it under the terms of the GNU General Public License as published by
7+
# the Free Software Foundation; either version 2 of the License, or
8+
# (at your option) any later version.
9+
#
10+
# This program is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
# GNU General Public License for more details.
14+
#
15+
# You should have received a copy of the GNU General Public License
16+
# along with this program; if not, write to the Free Software
17+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18+
#
19+
import remap
20+

src/emc/usr_intf/pncconf/pncconf.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,27 @@ def buid_config(self):
387387

388388
file.close()
389389

390+
# copy files for Gmoccapy remaps M6 and m61
391+
if self.d.frontend == _PD._GMOCCAPY:
392+
393+
# source directory
394+
dirgmoccapy = os.path.join(BASE, "share", "linuxcnc", "pncconf", "gmoccapy")
395+
if not os.path.exists(dirgmoccapy):
396+
dirgmoccapy = os.path.join(BASE, "src", "emc", "usr_intf", "pncconf", "gmoccapy")
397+
srcmacros = os.path.join(dirgmoccapy, "macros")
398+
srcpython = os.path.join(dirgmoccapy, "python")
399+
400+
# destination directory
401+
dstmacros = os.path.join(base, "macros")
402+
dstpython = os.path.join(base, "python")
403+
404+
# copy files
405+
if not os.path.exists(dstmacros):
406+
shutil.copytree(srcmacros, dstmacros)
407+
408+
if not os.path.exists(dstpython):
409+
shutil.copytree(srcpython, dstpython)
410+
390411
if self.warning_dialog(self._p.MESS_QUIT,False):
391412
Gtk.main_quit()
392413

0 commit comments

Comments
 (0)