From 475e12883b9eb2a5bf84f152fcc89187e2958ba4 Mon Sep 17 00:00:00 2001 From: "ton, LinuxCNCMESA" Date: Wed, 24 Apr 2019 16:01:45 +0200 Subject: [PATCH] gmoccapy toolchange works now --- custom.hal | 4 - gmoccapy_preferences | 76 +++++++++++++++++ macros/change.ngc | 75 +++++++++++++++++ macros/on_abort.ngc | 9 ++ mesa_2019.hal | 7 ++ mesa_2019.ini | 51 ++++++++++- postgui.hal | 11 +-- python/remap.py | 19 +++++ python/stdglue.py | 195 +++++++++++++++++++++++++++++++++++++++++++ python/toplevel.py | 20 +++++ tool.tbl | 12 +-- 11 files changed, 462 insertions(+), 17 deletions(-) create mode 100644 gmoccapy_preferences create mode 100644 macros/change.ngc create mode 100644 macros/on_abort.ngc create mode 100644 python/remap.py create mode 100644 python/stdglue.py create mode 100644 python/toplevel.py diff --git a/custom.hal b/custom.hal index d822324..485c8ef 100644 --- a/custom.hal +++ b/custom.hal @@ -16,7 +16,3 @@ net spindle-at-speed => spindle.0.at-speed - - - - diff --git a/gmoccapy_preferences b/gmoccapy_preferences new file mode 100644 index 0000000..26c2992 --- /dev/null +++ b/gmoccapy_preferences @@ -0,0 +1,76 @@ +[DEFAULT] +blockheight = 0.0 +spindle_start_rpm = 300.0 +scale_jog_vel = 27.0 +scale_spindle_override = 1 +scale_feed_override = 1 +scale_rapid_override = 1 +hide_turtle_jog_button = False +turtle_jog_factor = 20 +dro_size = 28 +open_file = +screen1 = window +x_pos = 40 +y_pos = 30 +width = 979 +height = 750 +gtk_theme = Follow System Theme +grid_size = 1.0 +view = p +mouse_btn_mode = 4 +hide_cursor = False +system_name_tool = Tool +system_name_g5x = G5x +system_name_rot = Rot +system_name_g92 = G92 +system_name_g54 = G54 +system_name_g55 = G55 +system_name_g56 = G56 +system_name_g57 = G57 +system_name_g58 = G58 +system_name_g59 = G59 +system_name_g59.1 = G59.1 +system_name_g59.2 = G59.2 +system_name_g59.3 = G59.3 +jump_to_dir = /home/ton +show_keyboard_on_offset = False +show_keyboard_on_tooledit = False +show_keyboard_on_edit = False +show_keyboard_on_mdi = False +spindle_bar_min = 3000.0 +spindle_bar_max = 21000.0 +x_pos_popup = 45.0 +y_pos_popup = 55 +width_popup = 250.0 +max_messages = 10 +message_font = sans 10 +use_frames = True +show_dro_btn = True +use_auto_units = False +probeheight = 25.4 +searchvel = 75.0 +probevel = 10.0 +use_toolmeasurement = True +reload_tool = True +blockdel = False +opstop = False +enable_dro = False +show_offsets = False +show_dtg = False +view_tool_path = True +view_dimension = True +gremlin_view = rbt_view_p +run_from_line = no_run +unlock_way = no +unlock_code = 123 +show_preview_on_offset = False +use_keyboard_shortcuts = True +abs_color = #0000FF +rel_color = #000000 +dtg_color = #FFFF00 +homed_color = #00FF00 +unhomed_color = #FF0000 +dro_digits = 3 +toggle_readout = True +tool_in_spindle = 24 + diff --git a/macros/change.ngc b/macros/change.ngc new file mode 100644 index 0000000..3c036b6 --- /dev/null +++ b/macros/change.ngc @@ -0,0 +1,75 @@ + +o sub +;(debug, in change tool_in_spindle=# current_pocket=#) +;(debug, selected_tool=# selected_pocket=#) + +;otherwise after the M6 this information is gone! +# = # +# = # + +; we must execute this only in the milltask interpreter +; or preview will break, so test for '#<_task>' which is 1 for +; the milltask interpreter and 0 in the UI's +O100 if [#<_task> EQ 0] + (debug, Task ist Null) +O100 return [999] +O100 endif + +;first go up +G53 G0 Z[#<_ini[CHANGE_POSITION]Z>] +; then move to change position +G53 G0 X[#<_ini[CHANGE_POSITION]X>] Y[#<_ini[CHANGE_POSITION]Y>] + +; cancel tool offset +G49 + +; using the code being remapped here means 'use builtin behaviour' +M6 + +O200 if [#<_hal[gmoccapy.toolmeasurement]> EQ 0] +O200 return [3] ; indicate no tool measurement +O200 endif + +G53 G0 X[#<_ini[TOOLSENSOR]X>] Y[#<_ini[TOOLSENSOR]Y>] +G53 G0 Z[#<_ini[TOOLSENSOR]Z>] + +O300 if [#<_hal[gmoccapy.searchvel]> LE 0] +O300 return [-1] ; indicate searchvel <= 0 +O300 endif + +O400 if [#<_hal[gmoccapy.probevel]> LE 0] +O400 return [-2] ; indicate probevel <= 0 +O400 endif + +F #<_hal[gmoccapy.searchvel]> +G91 +G38.2 Z #<_ini[TOOLSENSOR]MAXPROBE> +G0 Z2 +; This is commented out only for sim. +F #<_hal[gmoccapy.probevel]> +G38.2 Z-4 + +O500 if [#5070 EQ 0] +G90 +O500 return [-3] ; indicate probe contact failure to epilog +O500 endif + +G90 +G53 G0 Z[#<_ini[CHANGE_POSITION]Z>] + +# = #5063 +# = #<_hal[gmoccapy.probeheight]> +# = #<_hal[gmoccapy.blockheight]> + +;(DEBUG, # # #) + +G10 L1 P# Z[# - #<_hal[gmoccapy.probeheight]> + #<_hal[gmoccapy.blockheight]>] +G43 + +;G10 L1 P# Z# +;G10 L2 P0 Z[# + # + #] + +; signal success be returning a value > 0: +o endsub [1] + + diff --git a/macros/on_abort.ngc b/macros/on_abort.ngc new file mode 100644 index 0000000..da9f690 --- /dev/null +++ b/macros/on_abort.ngc @@ -0,0 +1,9 @@ +% +o sub + +G90 +G40 +G49 + +o endsub +% diff --git a/mesa_2019.hal b/mesa_2019.hal index a9c9923..8a1a423 100644 --- a/mesa_2019.hal +++ b/mesa_2019.hal @@ -29,6 +29,13 @@ addf pid.2.do-pid-calcs servo-thread addf pid.3.do-pid-calcs servo-thread addf hm2_[HOSTMOT2](BOARD).0.write servo-thread + +loadusr -W hal_manualtoolchange +net tool-change iocontrol.0.tool-change => hal_manualtoolchange.change +net tool-changed iocontrol.0.tool-changed <= hal_manualtoolchange.changed +net tool-number iocontrol.0.tool-prep-number => hal_manualtoolchange.number +net tool-prepare-loopback iocontrol.0.tool-prepare => iocontrol.0.tool-prepared + # Joint 0 # axis enable chain newsig emcmot.0.enable bit diff --git a/mesa_2019.ini b/mesa_2019.ini index 4d91b5e..a285b3d 100644 --- a/mesa_2019.ini +++ b/mesa_2019.ini @@ -18,12 +18,22 @@ SSERIAL_PORT = 1 DISPLAY = gmoccapy POSITION_OFFSET = RELATIVE POSITION_FEEDBACK = COMMANDED -MAX_FEED_OVERRIDE = 1.6 CYCLE_TIME = 0.1 INTRO_GRAPHIC = emc2.gif INTRO_TIME = 0 OPEN_FILE = "" + +PREFERENCE_FILE_PATH = gmoccapy_preferences +DEFAULT_LINEAR_VELOCITY = 166.666 +MAX_LINEAR_VELOCITY = 166.666 +MAX_FEED_OVERRIDE = 1.5 +MAX_SPINDLE_OVERRIDE = 1.2 +MIN_SPINDLE_OVERRIDE = 0.5 +PROGRAM_PREFIX = ../../nc_files/ + + + EMBED_TAB_NAME=Probe Screen EMBED_TAB_LOCATION = ntb_preview EMBED_TAB_COMMAND = gladevcp -x {XID} -u python/probe_screen.py probe_icons/probe_screen.glade @@ -32,6 +42,14 @@ EMBED_TAB_NAME = Camera EMBED_TAB_LOCATION = ntb_preview EMBED_TAB_COMMAND = mplayer -quiet -msglevel all=-1 -wid {XID} tv://0 -vf rectangle=-1:2:-1:240,rectangle=2:-1:320:-1 +EMBED_TAB_NAME = DRO +EMBED_TAB_LOCATION = ntb_user_tabs +EMBED_TAB_COMMAND = gladevcp -x {XID} dro.glade + +EMBED_TAB_NAME = Second user tab +EMBED_TAB_LOCATION = ntb_preview +EMBED_TAB_COMMAND = gladevcp -x {XID} vcp_box.glade + [KINS] KINEMATICS = trivkins coordinates=XYYZ kinstype=BOTH @@ -44,6 +62,33 @@ TOOL_TABLE = tool.tbl [RS274NGC] PARAMETER_FILE = mesa_2019.var +SUBROUTINE_PATH = macros + +# Enables the reading of INI and HAL values from gcode +FEATURES=12 + +# is the sub, with is called when a error during tool change happens +ON_ABORT_COMMAND=O call + +# The remap code +REMAP=M6 modalgroup=6 prolog=change_prolog ngc=change epilog=change_epilog + +[TOOLSENSOR] +X = 100 +Y = 10 +Z = -20 +MAXPROBE = -20 + +[CHANGE_POSITION] +X = 150 +Y = 10 +Z = -2 + +[PYTHON] +# The path to start a search for user modules +PATH_PREPEND = python +# The start point for all. +TOPLEVEL = python/toplevel.py [EMCMOT] EMCMOT = motmod @@ -60,11 +105,13 @@ ANGULAR_UNITS = degree MAX_LINEAR_VELOCITY = 45 [HAL] +#TWOPASS = ON HALFILE = mesa_2019.hal HALFILE = io.hal HALFILE = custom.hal -HALFILE = postgui.hal +#HALFILE = postgui.hal HALUI = halui +POSTGUI_HALFILE = postgui.hal HALFILE = LIB:xhc-hb04.tcl diff --git a/postgui.hal b/postgui.hal index c1f8dc9..59979ab 100644 --- a/postgui.hal +++ b/postgui.hal @@ -21,8 +21,9 @@ net estop-loop hm2_7i96.0.ssr.00.out-01 #net tool-prep-loop iocontrol.0.tool-prepare => iocontrol.0.tool-prepared #net tool-change-loop iocontrol.0.tool-change => iocontrol.0.tool-changed -loadusr -W hal_manualtoolchange -net tool-change iocontrol.0.tool-change => hal_manualtoolchange.change -net tool-changed iocontrol.0.tool-changed <= hal_manualtoolchange.changed -net tool-number iocontrol.0.tool-prep-number => hal_manualtoolchange.number -net tool-prepare-loopback iocontrol.0.tool-prepare => iocontrol.0.tool-prepared +net tooloffset-x gmoccapy.tooloffset-x <= motion.tooloffset.x +net tooloffset-z gmoccapy.tooloffset-z <= motion.tooloffset.z + + + + diff --git a/python/remap.py b/python/remap.py new file mode 100644 index 0000000..8cb7893 --- /dev/null +++ b/python/remap.py @@ -0,0 +1,19 @@ +# This is a component of LinuxCNC +# Copyright 2011, 2012, 2013, 2014 Dewey Garrett , +# Michael Haberler , Norbert Schechner +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +from stdglue import * diff --git a/python/stdglue.py b/python/stdglue.py new file mode 100644 index 0000000..edd0cb2 --- /dev/null +++ b/python/stdglue.py @@ -0,0 +1,195 @@ +# This is a component of LinuxCNC +# Copyright 2014 Norbert Schechner +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# gmoccapy - Remap of M6 for auto tool measurement + +import os +import sys +import emccanon +from interpreter import * +from gscreen import preferences +throw_exceptions = 1 + +debug = False +if debug: + pydevdir = '/home/emcmesa/Aptana_Studio_3/plugins/org.python.pydev_2.7.0.2013032300/pysrc' + + # the 'emctask' module is present only in the milltask instance, otherwise both the UI and + # milltask would try to connect to the debug server. + + if os.path.isdir( pydevdir ) and 'emctask' in sys.builtin_module_names: + sys.path.append( pydevdir ) + sys.path.insert( 0, pydevdir ) + try: + import pydevd + emccanon.MESSAGE( "pydevd imported, connecting to Eclipse debug server..." ) + pydevd.settrace() + except: + emccanon.MESSAGE( "no pydevd module found" ) + pass + +# REMAP=M6 modalgroup=6 prolog=change_prolog ngc=change epilog=change_epilog +# exposed parameters: +# # +# # +# # +# # + +def change_prolog(self, **words): + try: + # this is relevant only when using iocontrol-v2. + if self.params[5600] > 0.0: + if self.params[5601] < 0.0: + self.set_errormsg("Toolchanger hard fault %d" % (int(self.params[5601]))) + return INTERP_ERROR + print "change_prolog: Toolchanger soft fault %d" % int(self.params[5601]) + + if self.selected_pocket < 0: + self.set_errormsg("M6: no tool prepared") + return INTERP_ERROR + + if self.cutter_comp_side: + self.set_errormsg("Cannot change tools with cutter radius compensation on") + return INTERP_ERROR + self.params["tool_in_spindle"] = self.current_tool + self.params["selected_tool"] = self.selected_tool + self.params["current_pocket"] = self.current_pocket # this is probably nonsense + self.params["selected_pocket"] = self.selected_pocket + return INTERP_OK + + except Exception, e: + self.set_errormsg("M6/change_prolog: %s" % (e)) + return INTERP_ERROR + +def change_epilog(self, **words): + try: + if not self.value_returned: + r = self.blocks[self.remap_level].executing_remap + self.set_errormsg("the %s remap procedure %s did not return a value" + % (r.name,r.remap_ngc if r.remap_ngc else r.remap_py)) + return INTERP_ERROR + + if self.return_value > 0.0: + if self.return_value == 3: + message = "No tool measurement ! Please take care of the entry in the tool table" + emccanon.MESSAGE(message) + return INTERP_OK + else: + if self.return_value == -1: + message = "Searchvel <= 0, not permitted!, Please correct INI Settings." + elif self.return_value == -2: + message = "Probevel <= 0, not permitted!, Please correct INI Settings." + elif self.return_value == -3: + message = "Probe contact failiure !!" + else: + message = "M6 aborted (return code %.1f)" % (self.return_value) + self.set_errormsg(message) + return INTERP_ERROR + + except Exception, e: + self.set_errormsg("M6/change_epilog: %s" % (e)) + return INTERP_ERROR + + +_uvw = ("u","v","w","a","b","c") +_xyz = ("x","y","z","a","b","c") +# given a plane, return sticky words, incompatible axis words and plane name +# sticky[0] is also the movement axis +_compat = { + emccanon.CANON_PLANE_XY : (("z","r"),_uvw,"XY"), + emccanon.CANON_PLANE_YZ : (("x","r"),_uvw,"YZ"), + emccanon.CANON_PLANE_XZ : (("y","r"),_uvw,"XZ"), + emccanon.CANON_PLANE_UV : (("w","r"),_xyz,"UV"), + emccanon.CANON_PLANE_VW : (("u","r"),_xyz,"VW"), + emccanon.CANON_PLANE_UW : (("v","r"),_xyz,"UW")} + +# extract and pass parameters from current block, merged with extra parameters on a continuation line +# keep tjose parameters across invocations +# export the parameters into the oword procedure +def cycle_prolog(self,**words): + # self.sticky_params is assumed to have been initialized by the + # init_stgdlue() method below + global _compat + try: + # determine whether this is the first or a subsequent call + c = self.blocks[self.remap_level] + r = c.executing_remap + if c.g_modes[1] == r.motion_code: + # first call - clear the sticky dict + self.sticky_params[r.name] = dict() + + self.params["motion_code"] = c.g_modes[1] + + (sw,incompat,plane_name) =_compat[self.plane] + for (word,value) in words.items(): + # inject current parameters + self.params[word] = value + # record sticky words + if word in sw: + if self.debugmask & 0x00080000: print "%s: record sticky %s = %.4f" % (r.name,word,value) + self.sticky_params[r.name][word] = value + if word in incompat: + return "%s: Cannot put a %s in a canned cycle in the %s plane" % (r.name, word.upper(), plane_name) + + # inject sticky parameters which were not in words: + for (key,value) in self.sticky_params[r.name].items(): + if not key in words: + if self.debugmask & 0x00080000: print "%s: inject sticky %s = %.4f" % (r.name,key,value) + self.params[key] = value + + if not "r" in self.sticky_params[r.name]: + return "%s: cycle requires R word" % (r.name) + else: + if self.sticky_params[r.name] <= 0.0: + return "%s: R word must be > 0 if used (%.4f)" % (r.name, words["r"]) + + if "l" in words: + # checked in interpreter during block parsing + # if l <= 0 or l not near an int + self.params["l"] = words["l"] + + if "p" in words: + p = words["p"] + if p < 0.0: + return "%s: P word must be >= 0 if used (%.4f)" % (r.name, p) + self.params["p"] = p + + if self.feed_rate == 0.0: + return "%s: feed rate must be > 0" % (r.name) + if self.feed_mode == INVERSE_TIME: + return "%s: Cannot use inverse time feed with canned cycles" % (r.name) + if self.cutter_comp_side: + return "%s: Cannot use canned cycles with cutter compensation on" % (r.name) + return INTERP_OK + + except Exception, e: + raise + return "cycle_prolog failed: %s" % (e) + +# make sure the next line has the same motion code, unless overriden by a +# new G code +def cycle_epilog(self,**words): + try: + c = self.blocks[self.remap_level] + self.motion_mode = c.executing_remap.motion_code # retain the current motion mode + return INTERP_OK + except Exception, e: + return "cycle_epilog failed: %s" % (e) + +# this should be called from TOPLEVEL __init__() +def init_stdglue(self): + self.sticky_params = dict() diff --git a/python/toplevel.py b/python/toplevel.py new file mode 100644 index 0000000..50e3edf --- /dev/null +++ b/python/toplevel.py @@ -0,0 +1,20 @@ +# This is a component of LinuxCNC +# Copyright 2011, 2013, 2014 Dewey Garrett , +# Michael Haberler , Norbert Schechner +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +import remap + diff --git a/tool.tbl b/tool.tbl index 1fbe95f..33276c9 100644 --- a/tool.tbl +++ b/tool.tbl @@ -1,6 +1,6 @@ -T0 P0 X0.0 Y0.0 Z0.0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.0 I0.0 J0.0 Q0.0 ; -T0 P0 X0.0 Y0.0 Z0.0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.0 I0.0 J0.0 Q0.0 ; -T0 P0 X0.0 Y0.0 Z0.0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.0 I0.0 J0.0 Q0.0 ; -T1 P1 X0.0 Y0.0 Z0.0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.0 I0.0 J0.0 Q0.0 ; -T42 P42 X1.0 Y1.0 Z1.0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D6.35 I0.0 J0.0 Q0.0 ;added 20190422 -T24 P24 X0.0 Y0.0 Z0.0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D6.35 I0.0 J0.0 Q0.0 ;comment +T0 P0 ; +T0 P0 ; +T0 P0 ; +T1 P1 ; +T42 P42 D6.350000 X+1.000000 Y+1.000000 Z-63.635237 ;added 20190422 +T24 P24 D6.350000 ;comment